Skip to content

Commit c78e128

Browse files
committed
refactoring code
1 parent 8347274 commit c78e128

File tree

3 files changed

+190
-141
lines changed

3 files changed

+190
-141
lines changed
Lines changed: 5 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,14 @@
11
package org.ngbsn.generator;
22

3-
import org.apache.commons.text.CaseUtils;
4-
import org.apache.commons.text.WordUtils;
53
import org.ngbsn.model.Column;
6-
import org.ngbsn.model.EmbeddableClass;
74
import org.ngbsn.model.ForeignKeyConstraint;
85
import org.ngbsn.model.Table;
9-
import org.ngbsn.model.annotations.fieldAnnotations.*;
106

11-
import java.util.HashSet;
127
import java.util.List;
138
import java.util.Optional;
14-
import java.util.Set;
15-
import java.util.stream.Collectors;
16-
import java.util.stream.Stream;
179

18-
import static org.ngbsn.generator.ModelGenerator.tablesMap;
10+
import static org.ngbsn.generator.BiDirectionalMappingsGenerator.addBiDirectionalMappings;
11+
import static org.ngbsn.generator.UniDirectionalMappingsGenerator.addBothSideUniDirectionalMappings;
1912

2013
/**
2114
* This class contains logic for generating all the association mappings
@@ -29,7 +22,7 @@ public static void generateMappings(final Table table) {
2922
//Case: There is only 1 Foreign key or 1 Composite Foreign Key
3023
//Treat this as a regular table and add a new column with for parent field with @ManyToOne
3124
//and add a new column in ReferencedTable for child field with @OneToMany
32-
addBothUnidirectionalMappings(table, foreignKeyConstraintList.get(0));
25+
addBothSideUniDirectionalMappings(table, foreignKeyConstraintList.get(0));
3326

3427
} else {
3528
//Case: There are multiple Foreign Keys or multiple Composite Foreign Keys
@@ -39,146 +32,17 @@ public static void generateMappings(final Table table) {
3932
if (optionalKey.isEmpty() && foreignKeyConstraintList.size() == 2) {
4033
//Case: All fields are foreign keys. Also, the relation exits between 2 entities only
4134
//Remove this link entity from the tablesMap as separate entity is not needed to track Link Table. Use @ManyToMany on other 2 entities
42-
tablesMap.remove(table.getTableName());
43-
Table table1 = tablesMap.get(foreignKeyConstraintList.get(0).getReferencedTableName());
44-
Table table2 = tablesMap.get(foreignKeyConstraintList.get(1).getReferencedTableName());
45-
46-
//Adding @ManyToMany and @JoinTable to table1
47-
Column column1 = new Column();
48-
column1.setFieldName(CaseUtils.toCamelCase(table2.getTableName(), false, '_'));
49-
column1.setType(table2.getClassName());
50-
column1.getAnnotations().add(ManyToManyAnnotation.builder().build().toString());
51-
Set<JoinColumnAnnotation> joinColumnAnnotations = new HashSet<>();
52-
for (String column : foreignKeyConstraintList.get(0).getColumns()) {
53-
joinColumnAnnotations.add(JoinColumnAnnotation.builder().name(column).build());
54-
}
55-
Set<JoinColumnAnnotation> joinInverseColumnAnnotations = new HashSet<>();
56-
for (String column : foreignKeyConstraintList.get(1).getColumns()) {
57-
joinInverseColumnAnnotations.add(JoinColumnAnnotation.builder().name(column).build());
58-
}
59-
column1.getAnnotations().add(JoinTableAnnotation.builder().tableName(table.getTableName()).joinColumns(joinColumnAnnotations).inverseJoinColumns(joinInverseColumnAnnotations).build().toString());
60-
table1.getColumns().add(column1);
61-
62-
//Adding @ManyToMany(mappedBy) to table2
63-
Column column2 = new Column();
64-
column2.setFieldName(CaseUtils.toCamelCase(table1.getTableName(), false, '_'));
65-
column2.setType(table1.getClassName());
66-
column2.getAnnotations().add(ManyToManyAnnotation.builder().mappedBy(column1.getFieldName()).build().toString());
67-
table2.getColumns().add(column2);
35+
addBiDirectionalMappings(table, foreignKeyConstraintList);
6836

6937
} else {
7038
//Case1: There are some fields that are not foreign keys. So separate entity is needed to track Link Table
7139
//Case2: All fields are foreign keys. But, the relation exits between 2 or more entities
7240
//Add @ManyToOne for each foreignKey and corresponding @OneToMany in referenced Table
7341
foreignKeyConstraintList.forEach(foreignKeyConstraint -> {
74-
addBothUnidirectionalMappings(table, foreignKeyConstraint);
42+
addBothSideUniDirectionalMappings(table, foreignKeyConstraint);
7543
});
7644
}
7745
}
7846

7947
}
80-
81-
/**
82-
* This method will handle each foreign key constraint in the table.
83-
*
84-
* @param table table
85-
* @param foreignKeyConstraint foreignKeyConstraint
86-
*/
87-
private static void addBothUnidirectionalMappings(Table table, ForeignKeyConstraint foreignKeyConstraint) {
88-
Table referencedTable = tablesMap.get(foreignKeyConstraint.getReferencedTableName());
89-
//In the Child table, create a new column having field name as Parent(Referenced) Table.
90-
Column parentTableField = new Column();
91-
parentTableField.setFieldName(CaseUtils.toCamelCase(referencedTable.getTableName(), false, '_'));
92-
parentTableField.setType(referencedTable.getClassName());
93-
parentTableField.getAnnotations().add(new ManyToOneAnnotation().toString());
94-
table.getColumns().add(parentTableField);
95-
96-
//In the Parent(Referenced) table, create a new column having field name as child Table.
97-
Column childTableField = new Column();
98-
childTableField.setFieldName(CaseUtils.toCamelCase(table.getTableName(), false, '_'));
99-
childTableField.setType("Set<" + table.getClassName() + ">");
100-
childTableField.getAnnotations().add(OneToManyAnnotation.builder().mappedBy(parentTableField.getFieldName()).build().toString());
101-
referencedTable.getColumns().add(childTableField);
102-
103-
//get EmbeddedId for this table
104-
Optional<EmbeddableClass> optionalEmbeddableId = table.getEmbeddableClasses().stream().filter(EmbeddableClass::isEmbeddedId).findFirst();
105-
EmbeddableClass embeddableId = optionalEmbeddableId.orElse(null);
106-
Set<Column> allPrimaryKeyColumns = getAllPrimaryKeys(table, embeddableId); //get all primary keys
107-
108-
//Case: Composite Foreign key
109-
if (foreignKeyConstraint.getColumns().size() > 1) {
110-
Set<Column> setOfForeignKeyColumns = setOfForeignKeys(table, foreignKeyConstraint);
111-
//If composite foreign key is inside the composite primary key, don't remove them from table.
112-
//This case assumes there is a primary composite key
113-
//Add a @MapsId annotation to the referenced table field
114-
if (embeddableId != null && allPrimaryKeyColumns.containsAll(setOfForeignKeyColumns)) {
115-
EmbeddableClass foreignCompositeKeyEmbedded = new EmbeddableClass(); //Create a new embeddable for this foreign composite key
116-
String embeddableName = setOfForeignKeyColumns.stream().map(Column::getFieldName).collect(Collectors.joining());
117-
foreignCompositeKeyEmbedded.setClassName(WordUtils.capitalize(embeddableName));
118-
foreignCompositeKeyEmbedded.setFieldName(embeddableName);
119-
table.getEmbeddableClasses().add(foreignCompositeKeyEmbedded); //add new embeddable to the Table list of Embeddables
120-
setOfForeignKeyColumns.forEach(column -> {
121-
//add the individual foreign keys columns the newly created embeddable
122-
foreignCompositeKeyEmbedded.getColumns().add(column);
123-
//Remove the individual foreign keys from EmbeddedId and add the newly created embeddable into EmbeddedId
124-
embeddableId.getColumns().remove(column);
125-
});
126-
Column foreignCompositeField = new Column();
127-
foreignCompositeField.setType(foreignCompositeKeyEmbedded.getClassName());
128-
foreignCompositeField.setFieldName(foreignCompositeKeyEmbedded.getFieldName());
129-
embeddableId.getColumns().add(foreignCompositeField);
130-
131-
if(embeddableId.getFieldName() != null)
132-
parentTableField.getAnnotations().add(MapsIdAnnotation.builder().fieldName(foreignCompositeField.getFieldName()).build().toString());
133-
} else {
134-
//There is no primary Composite key
135-
//If composite foreign key is not inside the composite primary key, then remove it from the table
136-
setOfForeignKeyColumns.forEach(column -> table.getColumns().remove(column));
137-
}
138-
139-
Set<JoinColumnAnnotation> joinColumns = new HashSet<>();
140-
//Create the @JoinColumn annotations for the parentTableField
141-
for (int i = 0; i < foreignKeyConstraint.getColumns().size(); i++) {
142-
JoinColumnAnnotation joinColumnAnnotation = JoinColumnAnnotation.builder().name(foreignKeyConstraint.getColumns().get(i)).referencedColumnName(foreignKeyConstraint.getReferencedColumns().get(i)).build();
143-
joinColumns.add(joinColumnAnnotation);
144-
}
145-
parentTableField.getAnnotations().add(JoinColumnsAnnotation.builder().joinColumns(joinColumns).build().toString());
146-
147-
}
148-
//Case: Single Foreign Key
149-
else {
150-
//Get the foreign key column from the table
151-
Optional<Column> optionalColumn = table.getColumns().stream().filter(column -> column.getColumnName() != null && column.getColumnName().equals(foreignKeyConstraint.getReferencedColumns().get(0))).findFirst();
152-
if (optionalColumn.isPresent()) {
153-
Column foreignKeyColumn = optionalColumn.get();
154-
//Check if foreign key is also a primary key, by iterating through the primary key list
155-
Optional<Column> optionalColumnPrimaryForeign = allPrimaryKeyColumns.stream().filter(column -> column.getColumnName() != null && column.getColumnName().equals(foreignKeyColumn.getColumnName())).findFirst();
156-
optionalColumnPrimaryForeign.ifPresentOrElse(column -> {
157-
//If foreign key is a primary key, don't remove it from table.
158-
//Add a @MapsId annotation to the referenced table field
159-
parentTableField.getAnnotations().add(MapsIdAnnotation.builder().fieldName(column.getFieldName()).build().toString());
160-
}, () -> {
161-
//If foreign key is not a primary key, then remove it from the table
162-
optionalColumn.ifPresent(column -> table.getColumns().remove(column));
163-
});
164-
}
165-
//Add a @JoinColumn annotation for the referenced table field
166-
parentTableField.getAnnotations().add(JoinColumnAnnotation.builder().name(foreignKeyConstraint.getReferencedColumns().get(0)).referencedColumnName(foreignKeyConstraint.getReferencedColumns().get(0)).build().toString());
167-
}
168-
}
169-
170-
private static Set<Column> setOfForeignKeys(Table table, ForeignKeyConstraint foreignKeyConstraint) {
171-
Stream<Column> allTableForeignKeyColumns = table.getColumns().stream();
172-
Stream<Column> allEmbeddedForeignKeyColumns = table.getEmbeddableClasses().stream().flatMap(embeddableClass -> embeddableClass.getColumns().stream());
173-
return Stream.concat(allTableForeignKeyColumns, allEmbeddedForeignKeyColumns).filter(column -> foreignKeyConstraint.getColumns().stream().anyMatch(s -> s.equals(column.getColumnName()))).collect(Collectors.toSet());
174-
}
175-
176-
private static Set<Column> getAllPrimaryKeys(Table table, EmbeddableClass embeddableId) {
177-
//Get set of primary Keys
178-
if(embeddableId != null){
179-
return embeddableId.getColumns().stream().filter(Column::isPrimaryKey).collect(Collectors.toSet());
180-
}else{
181-
return table.getColumns().stream().filter(Column::isPrimaryKey).collect(Collectors.toSet());
182-
}
183-
}
18448
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package org.ngbsn.generator;
2+
3+
import org.apache.commons.text.CaseUtils;
4+
import org.ngbsn.model.Column;
5+
import org.ngbsn.model.ForeignKeyConstraint;
6+
import org.ngbsn.model.Table;
7+
import org.ngbsn.model.annotations.fieldAnnotations.JoinColumnAnnotation;
8+
import org.ngbsn.model.annotations.fieldAnnotations.JoinTableAnnotation;
9+
import org.ngbsn.model.annotations.fieldAnnotations.ManyToManyAnnotation;
10+
11+
import java.util.HashSet;
12+
import java.util.List;
13+
import java.util.Set;
14+
15+
import static org.ngbsn.generator.ModelGenerator.tablesMap;
16+
17+
public class BiDirectionalMappingsGenerator {
18+
static void addBiDirectionalMappings(Table table, List<ForeignKeyConstraint> foreignKeyConstraintList) {
19+
tablesMap.remove(table.getTableName());
20+
Table table1 = tablesMap.get(foreignKeyConstraintList.get(0).getReferencedTableName());
21+
Table table2 = tablesMap.get(foreignKeyConstraintList.get(1).getReferencedTableName());
22+
23+
//Adding @ManyToMany and @JoinTable to table1
24+
Column column1 = new Column();
25+
column1.setFieldName(CaseUtils.toCamelCase(table2.getTableName(), false, '_'));
26+
column1.setType(table2.getClassName());
27+
column1.getAnnotations().add(ManyToManyAnnotation.builder().build().toString());
28+
Set<JoinColumnAnnotation> joinColumnAnnotations = new HashSet<>();
29+
for (String column : foreignKeyConstraintList.get(0).getColumns()) {
30+
joinColumnAnnotations.add(JoinColumnAnnotation.builder().name(column).build());
31+
}
32+
Set<JoinColumnAnnotation> joinInverseColumnAnnotations = new HashSet<>();
33+
for (String column : foreignKeyConstraintList.get(1).getColumns()) {
34+
joinInverseColumnAnnotations.add(JoinColumnAnnotation.builder().name(column).build());
35+
}
36+
column1.getAnnotations().add(JoinTableAnnotation.builder().tableName(table.getTableName()).joinColumns(joinColumnAnnotations).inverseJoinColumns(joinInverseColumnAnnotations).build().toString());
37+
table1.getColumns().add(column1);
38+
39+
//Adding @ManyToMany(mappedBy) to table2
40+
Column column2 = new Column();
41+
column2.setFieldName(CaseUtils.toCamelCase(table1.getTableName(), false, '_'));
42+
column2.setType(table1.getClassName());
43+
column2.getAnnotations().add(ManyToManyAnnotation.builder().mappedBy(column1.getFieldName()).build().toString());
44+
table2.getColumns().add(column2);
45+
}
46+
}

0 commit comments

Comments
 (0)