Skip to content

Commit

Permalink
Merge pull request #2 from majora2007/feature/refactor
Browse files Browse the repository at this point in the history
Refactor
  • Loading branch information
majora2007 committed May 22, 2020
2 parents af37c79 + ce41fe8 commit fd67ea1
Show file tree
Hide file tree
Showing 12 changed files with 387 additions and 167 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,6 @@ dmypy.json

# Cython debug symbols
cython_debug/

# Generated .java files
*.java
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ example: python easyjava.py --entity ApplicationGroup --data "C:/Users/majora200
Word list came from:
https://raw.githubusercontent.com/first20hours/google-10000-english/master/google-10000-english-no-swears.txt

N.B. This code is pretty messy, I wrote this in 2 hours. Don't judge.

Build:
//pyinstaller --onefile --add-data "templates/*.*;./templates" --add-data "words.txt;." easyjava.py
Use:
Expand Down
103 changes: 5 additions & 98 deletions easyjava.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@

from gooey import Gooey, GooeyParser

import parse as parse
from typeinfo import TypeInfo
from util import camel_case, first_upper, first_chars, spinal_case, pyinstaller_get_full_path
from parse import DataParser
from generator import Generator

def get_argument(argument, default="None"):
if argument:
Expand All @@ -31,107 +30,15 @@ def init_args():
return parser.parse_args()



def parse_data(data_file):
types = []
lines = []
with open(data_file, 'r') as in_file:
lines = in_file.read().splitlines()


header = lines[0].split('|')
print(header)

line_data = []
for line in lines[1:]:
line_data = [c for c in line.split('|') if c != '' and c != ' ']
if len(line_data) is len(lines[0]):
break

for idx, cell in enumerate(line_data):
types.append(TypeInfo(parse.parse_type(cell, header[idx]), camel_case(header[idx]), header[idx]))

return types

def generate_entity_file(entity_name, types):
print('Generating {0}.java'.format(entity_name))

declarations = ''
for t in types:
declarations = declarations + t.generate_definitition() + '\n'

getter_setter = ''
for t in types:
getter_setter = getter_setter + t.generate_getter() + '\n' + t.generate_setter() + '\n'

to_string = '" ' + entity_name + ' ['

for t in types:
# "[%ENTITY%] [[%VARIABLE%]=" + [%VARIABLE%] + ", Name=" + name + ", Designation=" + designation + ", Salary=" + salary + "]";
to_string = to_string + t.var_name + '= " + ' + t.var_name + ' + ", '
to_string = ''.join(to_string[:len(to_string)-3]) + '"]";'

template = ''
path = pyinstaller_get_full_path('templates/Entity.java') #os.path.abspath(os.path.join(os.getcwd(), 'templates/Entity.java')) # Local only

with open(path, 'r') as in_file:
template = in_file.read()

template = template.replace('[%ENTITY%]', first_upper(entity_name)).replace('[%DECLARATION%]', declarations).replace('[%GETTER_SETTER%]', getter_setter).replace('[%TOSTRING%]', to_string)
with open(first_upper(entity_name) + '.java', 'w+') as out_file:
out_file.write(template)

def generate_entity_row_mapper(entity_name, types):
print('Generating {0}RowMapper.java'.format(entity_name))

template = ''
path = pyinstaller_get_full_path('templates/EntityRowMapper.java') # os.path.abspath(os.path.join(os.getcwd(), 'templates/EntityRowMapper.java')) # Local only

with open(path, 'r') as in_file:
template = in_file.read()

entity_var_name = first_chars(entity_name)

row_maps = ''
for t in types:
row_maps = row_maps + '\t\t' + entity_var_name + t.generate_rowmap_method() + '\n'

template = template.replace('[%ENTITY%]', first_upper(entity_name)).replace('[%ENTITYVAR%]', entity_var_name).replace('[%ROWMAPPER%]', row_maps)

with open(first_upper(entity_name) + 'RowMapper.java', 'w+') as out_file:
out_file.write(template)

def generate_entity_typescript(entity_name, types):
print('Generating {0}.ts'.format(spinal_case(entity_name).lower()))

template = ''
path = pyinstaller_get_full_path('templates/entity.ts') # os.path.abspath(os.path.join(os.getcwd(), 'templates/entity.ts')) # Local only
with open(path, 'r') as in_file:
template = in_file.read()

definitions = ''
for t in types:
definitions = definitions + ' ' + t.generate_ts_definition() + '\n'

template = template.replace('[%ENTITY%]', first_upper(entity_name)).replace('[%DEFINITIONS%]', definitions)

with open(spinal_case(entity_name).lower() + '.ts', 'w+') as out_file:
out_file.write(template)


@Gooey
def main(program_name='Easy Java', program_description='Generate POJOs and Row Mappers from data output'):
args = init_args()
entity = str(get_argument(args.entity))
data_file = str(get_argument(args.data))

types = parse_data(data_file)

generate_entity_file(entity, types)
generate_entity_row_mapper(entity, types)

if bool(args.typescript):
generate_entity_typescript(entity, types)
gen = Generator()
gen.load_file(data_file)
gen.generate_entity_files(entity, os.getcwd(), bool(args.typescript))


if __name__ == '__main__':
Expand Down
4 changes: 3 additions & 1 deletion easyjava.spec
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ gooey_root = os.path.dirname(gooey.__file__)
gooey_languages = Tree(os.path.join(gooey_root, 'languages'), prefix = 'gooey/languages')
gooey_images = Tree(os.path.join(gooey_root, 'images'), prefix = 'gooey/images')

import os
path = os.getcwd()

a = Analysis(['easyjava.py'],
pathex=['C:\\Users\\Joe\\Documents\\Projects\\Python\\easy-java'],
pathex=[path],
binaries=[],
datas=[('templates/*.*', './templates'), ('words.txt', '.')],
hiddenimports=['pkg_resources.py2_warn'],
Expand Down
165 changes: 165 additions & 0 deletions generator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
""" Resposible for generating code related to a language """
import os

from parse import DataParser
from util import camel_case, first_upper, first_chars, spinal_case, pyinstaller_get_full_path
from languagetype import Language

DEFINITION_TEMPLATE = '\tprivate {0} {1};'
GETTER_TEMPLATE = '\tpublic {0} get{1}() {{\n\t\treturn this.{2};\n\t}}'
SETTER_TEMPLATE = '\tpublic void set{0}({1} {2}) {{\n\t\tthis.{2} = {2};\n\t}}'
TOSTRING_TEMPLATE = '"[{0}] [{1}]"'
TOSTRING_INNER_TEMPLATE = '{}=" + {} + "'
ROWMAP_SETTER_TEMPLATE = '\t\t{0}.set{1}(rs.get{1}("{2}"));'
TYPESCRIPT_DEFINITION_TEMPLATE = ' {0}: {1};'


class Generator(object):
data = []
types = {}

def __init__(self):
self.parser = DataParser()


def load_file(self, data_file):
# Reset information about a file
self.data = []
self.types = {}

with open(data_file, 'r') as in_file:
lines = in_file.read().splitlines()


header = lines[0].split('|')
print(header)

for item in header:
self.types[item] = None

line_data = []
for line in lines[1:]:
line_data = [c for c in line.split('|') if c != '' and c != ' ']
if len(line_data) is len(lines[0]):
break # TODO: Is there a better way to handle this?

for idx, cell in enumerate(line_data):
self.types[header[idx]] = self.parser.parse_type(cell), camel_case(header[idx])

self._pretty_print_types()

def generate_entity_files(self, entity_name, folder_path, create_typescript=False):
if not os.path.isdir(folder_path):
os.mkdir(folder_path)

self._make_bean(entity_name, folder_path)
self._make_bean_rowmapper(entity_name, folder_path)
if create_typescript:
self._make_typescript(entity_name, folder_path)

def _make_bean(self, entity_name, folder_path):
if not entity_name[0].isupper():
entity_name = first_upper(entity_name)

print('Generating {0}.java'.format(entity_name))

declarations = '\n'.join(self._generate_definitions())
getter_setter = '\n'.join(self._generate_getters_setters())
to_string = self._generate_tostring(entity_name)

template = ''
path = pyinstaller_get_full_path('templates/Entity.java')

with open(path, 'r') as in_file:
template = in_file.read()

template = template.replace('[%ENTITY%]', entity_name).replace('[%DECLARATION%]', declarations).replace('[%GETTER_SETTER%]', getter_setter).replace('[%TOSTRING%]', to_string)

output_path = os.path.join(folder_path, entity_name + '.java')

with open(output_path, 'w+') as out_file:
out_file.write(template)

def _make_bean_rowmapper(self, entity_name, folder_path):
if not entity_name[0].isupper():
entity_name = first_upper(entity_name)

print('Generating {0}RowMapper.java'.format(entity_name))

template = ''
path = pyinstaller_get_full_path('templates/EntityRowMapper.java')

with open(path, 'r') as in_file:
template = in_file.read()

row_maps = '\n'.join(self._generate_rowmap(entity_name))

template = template.replace('[%ENTITY%]', first_upper(entity_name)).replace('[%ENTITYVAR%]', first_chars(entity_name)).replace('[%ROWMAPPER%]', row_maps)
output_path = os.path.join(folder_path, entity_name + 'RowMapper.java')

with open(output_path, 'w+') as out_file:
out_file.write(template)

def _make_typescript(self, entity_name, folder_path):
print('Generating {0}.ts'.format(spinal_case(entity_name).lower()))

template = ''
path = pyinstaller_get_full_path('templates/entity.ts')
with open(path, 'r') as in_file:
template = in_file.read()

definitions = '\n'.join(self._generate_typescript_definitions())

template = template.replace('[%ENTITY%]', first_upper(entity_name)).replace('[%DEFINITIONS%]', definitions)
output_path = os.path.join(folder_path, spinal_case(entity_name).lower() + '.ts')

with open(output_path, 'w+') as out_file:
out_file.write(template)

def _generate_typescript_definitions(self):
code_lines = []
for key in self.types:
var = self.types[key]
code_lines.append(TYPESCRIPT_DEFINITION_TEMPLATE.format(var[1], self.parser.translate_type(var[0], Language.Typescript)))
return code_lines

def _generate_rowmap(self, entity_name):
entity_var_name = first_chars(entity_name)

code_lines = []
for key in self.types:
var = self.types[key]
code_lines.append(ROWMAP_SETTER_TEMPLATE.format(entity_var_name, first_upper(var[1]), key))
return code_lines

def _generate_getters_setters(self):
code_lines = []
for key in self.types:
var = self.types[key]
java_type = self.parser.translate_type(var[0], Language.Java)
code_lines.append(GETTER_TEMPLATE.format(java_type, first_upper(var[1]), var[1]))
code_lines.append(SETTER_TEMPLATE.format(first_upper(java_type), java_type, var[1]))
return code_lines

def _generate_definitions(self):
code_lines = []
for key in self.types:
var = self.types[key]
code_lines.append(DEFINITION_TEMPLATE.format(self.parser.translate_type(var[0], Language.Java), var[1]))
return code_lines

def _generate_tostring(self, entity_name):
variables = []
for key in self.types:
var = self.types[key]
variables.append(first_upper(var[1]))
variables.append(var[1])
inner_format_templates = ', '.join([TOSTRING_INNER_TEMPLATE] * len(self.types.keys()))
return TOSTRING_TEMPLATE.format(entity_name, inner_format_templates.format(*variables))

def _pretty_print_types(self):
print('Parsed type info:')
# \tSQL -> camelCase: type
for key in self.types:
var = self.types[key]
print('\t{} -> {}: {}'.format(key, var[1], var[0]))
11 changes: 11 additions & 0 deletions languagetype.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from enum import Enum

class Language(Enum):
Java = 'java'
Typescript = 'typescript'

class LanguageType(Enum):
string = 'string'
integer = 'integer'
float = 'float'
boolean = 'boolean'
Loading

0 comments on commit fd67ea1

Please sign in to comment.