
org.nuiton.topia.templates.TopiaMetadataModelGenerator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of topia-templates-extension Show documentation
Show all versions of topia-templates-extension Show documentation
ObServe ToPIA templates extension module
The newest version!
package org.nuiton.topia.templates;
/*
* #%L
* ObServe Toolkit :: ToPIA Templates Extension
* %%
* Copyright (C) 2017 - 2018 IRD, Ultreia.io
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* .
* #L%
*/
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.File;
import java.io.Writer;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.eugene.EugeneCoreTagValues;
import org.nuiton.eugene.GeneratorUtil;
import org.nuiton.eugene.models.object.ObjectModel;
import org.nuiton.eugene.models.object.ObjectModelAttribute;
import org.nuiton.eugene.models.object.ObjectModelClass;
import org.nuiton.eugene.models.object.ObjectModelGenerator;
import org.nuiton.eugene.models.object.ObjectModelPackage;
import org.nuiton.topia.persistence.metadata.TopiaMetadataEntity;
import org.nuiton.topia.persistence.metadata.TopiaMetadataModel;
import org.nuiton.topia.persistence.metadata.TopiaMetadataModelVisitor;
/**
* Created on 03/01/16.
*
* @author Tony Chemit - [email protected]
* @plexus.component role="org.nuiton.eugene.Template" role-hint="org.nuiton.topia.templates.TopiaMetadataModelGenerator"
* @since 3.0.1
*/
public class TopiaMetadataModelGenerator extends ObjectModelGenerator {
private static final Log log = LogFactory.getLog(TopiaMetadataModelGenerator.class);
protected TopiaTemplateHelper templateHelper;
protected TopiaHibernateTagValues topiaHibernateTagValues;
protected EugeneCoreTagValues eugeneCoreTagValues;
public TopiaTemplateHelper getTemplateHelper() {
if (templateHelper == null) {
templateHelper = new TopiaTemplateHelper(model);
}
return templateHelper;
}
@Override
public void generateFromModel(Writer output, ObjectModel input) {
if (topiaHibernateTagValues == null) {
topiaHibernateTagValues = new TopiaHibernateTagValues();
}
List entityClasses = getTemplateHelper().getEntityClasses(model, true);
TopiaMetadataModel metadataModel = new TopiaMetadataModel();
Multimap> oneToManyAssociationInverses = ArrayListMultimap.create();
// Première passe pour construire toutes les entités
for (ObjectModelClass entityClass : entityClasses) {
buildMetadataEntity(entityClass, metadataModel, oneToManyAssociationInverses);
}
// On remplit désormais les oneToManyAssociationInverses
for (TopiaMetadataEntity metadataEntity : metadataModel) {
if (oneToManyAssociationInverses.containsKey(metadataEntity.getType())) {
for (Pair pair: oneToManyAssociationInverses.get(metadataEntity.getType())) {
String typeName = pair.getRight();
String columnName = pair.getLeft();
metadataEntity.addOneToManyAssociationInverse(metadataEntity, typeName, columnName);
}
}
}
// Seconde passe pour aggréger les héritages
for (ObjectModelClass entityClass : entityClasses) {
TopiaMetadataEntity metadataEntity = metadataModel.getEntity(entityClass.getName());
applyInheritance(metadataEntity, entityClass, metadataModel);
}
if (log.isDebugEnabled()) {
TopiaMetadataModelVisitor.PrintVisitor visitor = new TopiaMetadataModelVisitor.PrintVisitor(true, "\n");
metadataModel.accept(visitor);
log.info("MetadataModel:\n" + visitor);
}
Gson gson = new GsonBuilder().setPrettyPrinting().create();
gson.toJson(metadataModel, output);
}
@Override
public String getFilenameForModel(ObjectModel model) {
return getTopiaMetadataModelFilePath(model);
}
public String getTopiaMetadataModelFilePath(ObjectModel model) {
String packageName = getTemplateHelper().getDefaultPackage(this);
return (packageName + '.').replace('.', File.separatorChar) + model.getName() + "TopiaMetadataModel.json";
}
protected void applyInheritance(TopiaMetadataEntity metadataEntity, ObjectModelClass entityClass, TopiaMetadataModel metadataModel) {
boolean haveSuper = entityClass.getSuperclasses().size() > 0;
if (haveSuper) {
ObjectModelClass superClass = entityClass.getSuperclasses().iterator().next();
String parentName = superClass.getName();
Optional optionalEntity = metadataModel.getOptionalEntity(parentName);
if (optionalEntity.isPresent()) {
TopiaMetadataEntity parentMetadataEntity = optionalEntity.get();
parentMetadataEntity.putAll(metadataEntity);
applyInheritance(metadataEntity, superClass, metadataModel);
}
}
}
protected TopiaMetadataEntity buildMetadataEntity(ObjectModelClass entityClass, TopiaMetadataModel metadataModel, Multimap> oneToManyAssociationInverses) {
TopiaMetadataEntity metadataEntity;
String entityClassName = entityClass.getName();
Optional optionalClazz = metadataModel.getOptionalEntity(entityClassName);
if (optionalClazz.isPresent()) {
metadataEntity = optionalClazz.get();
} else {
if (isVerbose()) {
log.info("Start " + entityClassName);
}
ObjectModelPackage aPackage = model.getPackage(entityClass);
String dbSchemaName = topiaHibernateTagValues.getDbSchemaNameTagValue(entityClass, aPackage, model);
String dbTableName = templateHelper.getDbName(entityClass);
boolean haveSuper = entityClass.getSuperclasses().size() > 0;
String parent = null;
if (haveSuper) {
ObjectModelClass superClass = entityClass.getSuperclasses().iterator().next();
parent = superClass.getName();
}
metadataEntity = metadataModel.newEntity(parent, entityClassName, dbSchemaName, dbTableName);
Collection attributes = entityClass.getAttributes();
for (ObjectModelAttribute attr : attributes) {
ObjectModelAttribute reverse = attr.getReverseAttribute();
if (!attr.isNavigable()
&& !getTemplateHelper().hasUnidirectionalRelationOnAbstractType(reverse, model)
&& !attr.hasAssociationClass()) {
continue;
}
String name = attr.getName();
String attrColumn = templateHelper.getDbName(attr);
if (attr.getClassifier() == null || !getTemplateHelper().isEntity(attr.getClassifier())) {
String attrType = attr.getType();
switch (attrType) {
case "String":
attrType = "java.lang.String";
break;
case "Boolean":
attrType = "java.lang.Boolean";
break;
case "Byte":
attrType = "java.lang.Byte";
break;
case "Character":
attrType = "java.lang.Character";
break;
case "Short":
attrType = "java.lang.Short";
break;
case "Integer":
attrType = "java.lang.Integer";
break;
case "Long":
attrType = "java.lang.Long";
break;
case "Float":
attrType = "java.lang.Float";
break;
case "Double":
attrType = "java.lang.Double";
break;
}
metadataEntity.addProperty(name, attrType, attrColumn);
continue;
}
ObjectModelClass attributeClass = model.getClass(attr.getType());
Optional optionalAttributeClass = metadataModel.getOptionalEntity(attributeClass.getName());
TopiaMetadataEntity attributeClazz;
attributeClazz = optionalAttributeClass.orElseGet(() -> buildMetadataEntity(attributeClass, metadataModel, oneToManyAssociationInverses));
if (GeneratorUtil.isNMultiplicity(attr)) {
String reverseColumnName = templateHelper.getReverseDbName(attr);
if (GeneratorUtil.isNMultiplicity(attr.getReverseMaxMultiplicity()) && !attr.hasAssociationClass()) {
// many to many
String tableName = templateHelper.getManyToManyTableName(attr);
metadataEntity.addManyToManyAssociation(attributeClazz, name, attrColumn, tableName, reverseColumnName);
} else {
// one to many
if (reverseColumnName == null) {
reverseColumnName = entityClassName.toLowerCase();
}
boolean ordered = EugeneCoreTagValues.isOrdered(attr);
if (ordered) {
String extraColumn = reverseColumnName+ "_idx";
if (log.isInfoEnabled()) {
log.info("Found ordered " + attr + " -> " + extraColumn);
}
attributeClazz.addExtraColumn(extraColumn);
}
metadataEntity.addOneToManyAssociation(attributeClazz, name, attrColumn);
oneToManyAssociationInverses.put(attributeClazz.getType(), Pair.of(reverseColumnName,metadataEntity.getType()));
}
} else {
if (GeneratorUtil.isNMultiplicity(attr.getReverseMaxMultiplicity()) && !attr.hasAssociationClass()) {
// many to one
metadataEntity.addManyToOneAssociation(attributeClazz, name, attrColumn);
} else {
// one to one
metadataEntity.addReversedAssociation(attributeClazz, name, attrColumn);
}
}
}
if (isVerbose()) {
log.info("End " + entityClassName);
}
}
return metadataEntity;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy