From a62d5580d2f7f5ed32d01b146852710f48b011e6 Mon Sep 17 00:00:00 2001 From: Minh VU Date: Sun, 24 Mar 2024 00:05:18 +0100 Subject: [PATCH] Finished Generator Finished the version of Python. Rearrange DotUML --- .../diagramme_cas_utilisation | 0 DotUML/Diagramme_class/diagramme_class | 113 +++++++++++++++ .../explications diagrammes de classes | 0 DotUML/diagramme_class | 116 --------------- Generateur/DotUML.txt | 116 ++++++++++++++- Generateur/Read.py | 133 ++++++++++++++---- Generateur/erase.py | 7 + README.md | 4 +- 8 files changed, 341 insertions(+), 148 deletions(-) rename DotUML/{ => Diagramme_cas}/diagramme_cas_utilisation (100%) create mode 100644 DotUML/Diagramme_class/diagramme_class rename DotUML/{ => Diagramme_class}/explications diagrammes de classes (100%) delete mode 100644 DotUML/diagramme_class create mode 100644 Generateur/erase.py diff --git a/DotUML/diagramme_cas_utilisation b/DotUML/Diagramme_cas/diagramme_cas_utilisation similarity index 100% rename from DotUML/diagramme_cas_utilisation rename to DotUML/Diagramme_cas/diagramme_cas_utilisation diff --git a/DotUML/Diagramme_class/diagramme_class b/DotUML/Diagramme_class/diagramme_class new file mode 100644 index 0000000..dcceea8 --- /dev/null +++ b/DotUML/Diagramme_class/diagramme_class @@ -0,0 +1,113 @@ +ClassDiagram [frame=true framecolor=steelblue label="Class Diagram"] { + + class Parieur { + parieur_ID : int + aprieur_Nom : string + Solde : float + capital_jetons : int + placerUnPari() : void +} +class Sport { + sport_Nom : string + getNom() : string +} + class Football { +} + class MiTemps { + numéro_mitemps : int +} + +class Basket { +} + class QuartTemps { + numéro_quarttemps : int +} + +class Tennis { + +} + +class Sets { + numéro_set : int + } + +class CourseDeChevaux { + +} + class DataSource { + misesàjourData() : Data +} + +Football -g-> Sport +Basket -g-> Sport +Tennis -g-> Sport +CourseDeChevaux -g-> Sport + + +class Participant { + participant_ID : int + aprticipant_Nom : string + PArticipant_Type : string + getID() : int + getNom() : string + getType() : string +} + + class Bookmaker { + crediterParieur(pari:Pari) : void +} + + class Pari { + // attributs spécifiques au pari simple + pari_ID : int + Parieur : Parieur + Événement : événement + TypePari : string + RésultatParié : string + Montant : float + Cote : float + +} + + +class PariSimple { + // attributs spécifiques au pari simple + Issue : string + HeureLimite : datetime + PointsAvanceÉquipe1 : int + PointsAvanceÉquipe2 : int +} + +class PariAvancé { + // attributs spécifiques au pari avancé + Type : string + Intervalle : string + +} + class Événement { + event_ID : int + evennt_Nom : string + Date : date + Sport : string + Numéro_période : int + Score : string + getID() : int + getNom() : string + getDate() : date +} + +PariSimple -g-> Pari +PariAvancé -g-> Pari + +Événement "1" -- "1" Sport ; +Participant "0..*" -- "1" Événement ; + MiTemps "2" -c-> "1" Football ; + Sets "2..5" -c-> "1" Tennis ; + QuartTemps "4" -c-> "1" Basket ; + //DataSource -- Événement: Mise_à_jour_des_données ; + Événement "1" -- "0..*" PariSimple ; +Événement "1" -- "0..*" PariAvancé ; + Parieur "1" -- "0..*" Pari ; + Bookmaker "1" -- "0..*" Pari ; + + } diff --git a/DotUML/explications diagrammes de classes b/DotUML/Diagramme_class/explications diagrammes de classes similarity index 100% rename from DotUML/explications diagrammes de classes rename to DotUML/Diagramme_class/explications diagrammes de classes diff --git a/DotUML/diagramme_class b/DotUML/diagramme_class deleted file mode 100644 index ce36e03..0000000 --- a/DotUML/diagramme_class +++ /dev/null @@ -1,116 +0,0 @@ - -ClassDiagram [frame=true framecolor=steelblue label="Class Diagram"] { - - class parieur { - parieur_ID: int - aprieur_Nom: string - Solde: float - capital_jetons: int - placerUnPari(): void -} -class sport { - sport_Nom: string - getNom(): string -} - class football { -} - class miTemps { - numéro_mitemps: int -} - -class basket { - -} - class quartTemps { - numéro_quarttemps: int -} - -class tennis { - -} - class sets { - numéro_set: int - } - -class courseDeChevaux { - -} - class DataSource { - misesàjourData(): Data -} - - -sport <-g- football -sport <-g- basket -sport <-g- tennis -sport <-g- courseDeChevaux - - -class Participant { - participant_ID: int - aprticipant_Nom: string - PArticipant_Type: string - getID(): int - getNom(): string - getType(): string -} - class DataSource { - -} - class Bookmaker { - crediterParieur(pari: Pari): void -} - class pari { - // attributs spécifiques au pari simple - pari_ID: int - Parieur: Parieur - Événement: événement - TypePari: string - RésultatParié: string - Montant: float - Cote: float - -} - -class pariSimple { - // attributs spécifiques au pari simple - Issue: string - HeureLimite: datetime - PointsAvanceÉquipe1: int - PointsAvanceÉquipe2: int -} - -class pariAvancé { - // attributs spécifiques au pari avancé - Type: string - Intervalle: string - -} - class Événement { - event_ID: int - evennt_Nom: string - Date: date - Sport: string - Numéro_période: int - Score: string - getID(): int - getNom(): string - getDate(): date -} - pari <-g- pariSimple -pari <-g- pariAvancé - - - -Événement "1" -- "1" sport; -Participant "0..*" -- "1" Événement; - miTemps "2" -c-> "1" football; - sets "2..5" -c-> "1" tennis; - quartTemps "4" -c-> "1" basket; - DataSource -- Événement: Mise_à_jour_des_données; - Événement "0..*" -- "0..*" pariSimple; -Événement "0..*" -- "0..*" pariAvancé; - parieur "1" -- "0..*" pari; - Bookmaker "1" -- "0..*" pari; - - } diff --git a/Generateur/DotUML.txt b/Generateur/DotUML.txt index 0497055..c7f5985 100644 --- a/Generateur/DotUML.txt +++ b/Generateur/DotUML.txt @@ -1,7 +1,113 @@ ClassDiagram [frame=true framecolor=steelblue label="Class Diagram"] { - class Sport { - can_be_nul : boolean - id : int - } - Sport -g-> ABC \ No newline at end of file + class Parieur { + parieur_ID : int + aprieur_Nom : string + Solde : float + capital_jetons : int + placerUnPari() : void +} +class Sport { + sport_Nom : string + getNom() : string +} + class Football { +} + class MiTemps { + numéro_mitemps : int +} + +class Basket { +} + class QuartTemps { + numéro_quarttemps : int +} + +class Tennis { + +} + +class Sets { + numéro_set : int + } + +class CourseDeChevaux { + +} + class DataSource { + misesàjourData() : Data +} + +Football -g-> Sport +Basket -g-> Sport +Tennis -g-> Sport +CourseDeChevaux -g-> Sport + + +class Participant { + participant_ID : int + aprticipant_Nom : string + PArticipant_Type : string + getID() : int + getNom() : string + getType() : string +} + + class Bookmaker { + crediterParieur(pari:Pari) : void +} + + class Pari { + // attributs spécifiques au pari simple + pari_ID : int + Parieur : Parieur + Événement : événement + TypePari : string + RésultatParié : string + Montant : float + Cote : float + +} + + +class PariSimple { + // attributs spécifiques au pari simple + Issue : string + HeureLimite : datetime + PointsAvanceÉquipe1 : int + PointsAvanceÉquipe2 : int +} + +class PariAvancé { + // attributs spécifiques au pari avancé + Type : string + Intervalle : string + +} + class Événement { + event_ID : int + evennt_Nom : string + Date : date + Sport : string + Numéro_période : int + Score : string + getID() : int + getNom() : string + getDate() : date +} + +PariSimple -g-> Pari +PariAvancé -g-> Pari + +Événement "1" -- "1" Sport ; +Participant "0..*" -- "1" Événement ; + MiTemps "2" -c-> "1" Football ; + Sets "2..5" -c-> "1" Tennis ; + QuartTemps "4" -c-> "1" Basket ; + //DataSource -- Événement: Mise_à_jour_des_données ; + Événement "1" -- "0..*" PariSimple ; +Événement "1" -- "0..*" PariAvancé ; + Parieur "1" -- "0..*" Pari ; + Bookmaker "1" -- "0..*" Pari ; + + } \ No newline at end of file diff --git a/Generateur/Read.py b/Generateur/Read.py index f7bc789..4452d5a 100644 --- a/Generateur/Read.py +++ b/Generateur/Read.py @@ -1,7 +1,7 @@ +import glob import os import re -# inside_class = False file_class = None read = False @@ -13,9 +13,16 @@ content= file_uml.readlines() if not os.path.exists(path): os.mkdir(path) + +os.chdir(os.getcwd()+'/'+path) +for filename in glob.glob('*.java'): + os.remove(filename) + +#Check files if it exists def check_file(path_file): return os.path.exists(path_file) +# Modify text exists from from_ to to_ def modify(filepath, from_, to_): file = open(filepath,"r+") text = file.read() @@ -25,9 +32,60 @@ def modify(filepath, from_, to_): with open(filepath,'r+') as file: file.write(modified_text) +#Add @OneToMany and @ManyToOne to 2 classes -#Couper le fichier ligne par ligne +def onetomany(class_one, class_many): + + class_one_java = class_one + '.java' + class_many_java= class_many + '.java' + + # Insert the needed line @OneToMany + mappedBy = class_one.lower() + classes = class_many.lower() + 's' + assertion = '\t @OneToMany (mappedBy= "' + mappedBy + '") \n' + assertion = assertion + '\t public Collection<'+class_many+'> ' +classes+'; \n' + overwrite('public class',assertion, class_one_java, class_one_java,1) + + # Insert the needed line @ManyToOne + assertion = '\t @ManyToOne \n' + assertion = assertion + '\t public '+ class_one + ' '+ class_one.lower()+ '; \n' + overwrite('public class',assertion, class_many_java, class_many_java,1) + + +def onetoone(class_one, class_two): + + class_one_java = class_one + '.java' + class_two_java= class_two + '.java' + + class1 = class_one.lower() + class2 = class_two.lower() + + assertion = '\t @OneToOne \n' + + overwrite('public class',assertion+ '\t public '+class_two+' '+class2+ ' \n', class_one_java, class_one_java,1) + overwrite('public class', assertion+ '\t public '+class_one+' '+class1+ ' \n', class_two_java, class_two_java, 1) + +# Actually not overwrite, it creates an output file but in our project, I need output and input are same file +#String: line need to insert +def overwrite(find,string, input, output,option): + with open(input,'r') as input_file: + lines = input_file.readlines() + match_line_index= next ((i for i,line in enumerate(lines) if find in line), None) + + if match_line_index is not None: + with open(output,'w') as output: + if(option==1): + output.writelines(lines[:match_line_index + 1]) + output.write(string) + output.writelines(lines[match_line_index + 1:]) + elif(option==2): + output.write(string) + output.writelines(lines[:match_line_index + 1]) + output.writelines(lines[match_line_index + 1:]) + +#Cut the files into lines for line in content: + #skip first line if "ClassDiagram" in line: continue @@ -35,12 +93,12 @@ for line in content: #print(line) split_line=line.split() read=False - #Coupe la ligne par des morcreaux + #Cut lines into pieces print(split_line) print(len(split_line)) #Check if it is a blank line - if ( len(split_line)==0): + if ( len(split_line)==0 or '//' in line): continue else: # check "class X {" line @@ -55,7 +113,8 @@ for line in content: else: # Create the Java file file_class=open(class_java,'x') - file_class.write(f"public class {class_name} {{\n") + file_class.write("@Entity \n") + file_class.write('public class '+class_name +' { \n') inside_class = True #Check type of variables @@ -63,15 +122,17 @@ for line in content: file_class.write("\n") if(len(split_line)==3 and split_line[1]==":"): name_var =split_line[0] - if (split_line[2]=="boolean"): - type_var="Boolean" - elif (split_line[2]=="int"): + if (split_line[2]=="int"): type_var="Integer" - file_class.write("\t @Id \n") elif (split_line[2]=="void"): type_var="void" + else: + type_var=split_line[2].capitalize() file_class.write("\t @Column \n") - file_class.write(f"\t private {type_var} {name_var} \n") + if ("()" in name_var) or(type_var=="void"): + file_class.write(f"\t private {type_var} {name_var} {{}} \n") + else: + file_class.write(f"\t private {type_var} {name_var} ;\n") read = True if split_line[0]=='}' and len(split_line)==1: inside_class= False @@ -86,19 +147,39 @@ for line in content: class_java = class_name+'.java' class_heritage= split_line[2] - if check_file(class_java): - """ - file_class=open(class_java,'r+') - contents=file_class.readlines() - #Check if it has line public class X - for content in contents: - if 'public class' in content: - extends= "extends "+ class_heritage +" { \n" - content= content.replace('', 'public class X for Z') - file_class.write(content) - file_class.close() - break - """ - class_declaration= 'public class ' + class_name - modify(class_java,class_declaration,class_declaration+ " extends "+ class_heritage) - break \ No newline at end of file + if check_file(class_java): + class_declaration= 'public class ' + class_name + modify(class_java,class_declaration,class_declaration+ " extends "+ class_heritage) + break + + + # Check condition A "B" -- "C" D ; + if (len(split_line) == 6 and split_line[2] == '--' and split_line[5]==';'): + num1= split_line[1] + num2= split_line[3] + if(split_line[1]=='"1"' and split_line[3]!='"1"'): + onetomany(split_line[0], split_line[4]) + elif(split_line[3]=='"1"' and split_line[1]!='"1"'): + onetomany(split_line[4], split_line[0]) + elif(split_line[3]=='"1"' and split_line[1]=='"1"'): + onetoone(split_line[0], split_line[4]) + break + + # Check extends "X "a" -c-> "1" Y" ; + if (len(split_line) == 6 and split_line[2] == '-c->'): + class_name = split_line[0] + class_java = class_name + '.java' + + class_heritage = split_line[4] + class_heritage_java = class_heritage + '.java' + + modify(class_java,'@Entity','@Embeddable') + + embedded = '\t @Embedded \n' + if(split_line[1]=='"1"'): + embedded = embedded + '\t public '+class_heritage+ ' '+class_heritage.lower()+' ; \n' + overwrite('public class',embedded,class_heritage_java,class_heritage_java,1) + else: + embedded = embedded + '\t public Collection<' + class_name + '> ' + class_name.lower() + 's ; \n' + overwrite('public class', embedded, class_heritage_java, class_heritage_java, 1) + break \ No newline at end of file diff --git a/Generateur/erase.py b/Generateur/erase.py new file mode 100644 index 0000000..618c8e1 --- /dev/null +++ b/Generateur/erase.py @@ -0,0 +1,7 @@ +import glob +import os + +path='class' +os.chdir(os.getcwd()+'/'+path) +for filename in glob.glob('*.java'): + os.remove(filename) diff --git a/README.md b/README.md index 7ea87ca..9f010bd 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -##Description +## Description This is a project for 3rd year academic of Université de Rennes 1. This project have 3 main parts: DotUML, OpenXAVA and generator based on Python --- @@ -6,6 +6,8 @@ This is a project for 3rd year academic of Université de Rennes 1. This project > ### Disclaimer > I use `Python 3.10` so any superior version or lower will not be tested > In the code of **Read.py** it could be unusable if there are files has the same name which Python will generate. Please make sure that you have to delete the folder or change the path in **Read.py** +> Because it is very difficult to see which one is the key of the class so you have to decide which one is `@Id` after the generated files. +> All of lines have `//` as comment will be skipped in generated code. So make sure comments are not on the same line of code. --- ## Troubleshooting