org.nuiton.eugene.java.JavaGenerator Maven / Gradle / Ivy
/*
* #%L
* EUGene :: EUGene
*
* $Id: JavaGenerator.java 1254 2013-05-24 21:16:34Z tchemit $
* $HeadURL: http://svn.nuiton.org/svn/eugene/tags/eugene-2.6.3/eugene/src/main/java/org/nuiton/eugene/java/JavaGenerator.java $
* %%
* Copyright (C) 2004 - 2011 CodeLutin, Chatellier Eric
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser 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 Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
package org.nuiton.eugene.java;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.eugene.GeneratorUtil;
import org.nuiton.eugene.java.extension.AnnotationsManagerExtension;
import org.nuiton.eugene.java.extension.ImportsManagerExtension;
import org.nuiton.eugene.models.object.ObjectModelAttribute;
import org.nuiton.eugene.models.object.ObjectModelClass;
import org.nuiton.eugene.models.object.ObjectModelClassifier;
import org.nuiton.eugene.models.object.ObjectModelElement;
import org.nuiton.eugene.models.object.ObjectModelEnumeration;
import org.nuiton.eugene.models.object.ObjectModelGenerator;
import org.nuiton.eugene.models.object.ObjectModelInterface;
import org.nuiton.eugene.models.object.ObjectModelOperation;
import org.nuiton.eugene.models.object.ObjectModelParameter;
import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
/**
* JavaGenerator
*
* Created: 22 oct. 2009
*
* @author fdesbois
* @version $Id: JavaGenerator.java 1254 2013-05-24 21:16:34Z tchemit $
*
* Stupid generation of an ObjectModel with Java classes and interfaces.
* Use of ImportsManager to get imports for a classifier (added in model in the JavaBuilder which construct
* the ObjectModel).
*
* The JavaGenerator is based on a ObjectModelGenerator : Java classes are represented by ObjectModelClass, ...
*
* @plexus.component role="org.nuiton.eugene.Template" role-hint="org.nuiton.eugene.java.JavaGenerator"
*/
public class JavaGenerator extends ObjectModelGenerator {
private static final Log log = LogFactory.getLog(JavaGenerator.class);
protected int innerLevel;
protected String prefix;
@Override
public String getFilenameForClass(ObjectModelClass clazz) {
return getFilenameForClassifier(clazz);
}
@Override
public String getFilenameForInterface(ObjectModelInterface interfacez) {
return getFilenameForClassifier(interfacez);
}
@Override
public String getFilenameForEnumeration(ObjectModelEnumeration enumeration)
{
return getFilenameForClassifier(enumeration);
}
@Override
public String getFilenameForClassifier(ObjectModelClassifier clazz) {
String s = clazz.getQualifiedName();
int index = s.indexOf("<");
if (index > -1) {
s = s.substring(0, index);
}
return s.replace('.', File.separatorChar) + ".java";
}
/**
* Generate from all classes.
*
* @param output Writer for generating the java file
* @param input Class to manage for creating an output file
* @throws IOException if any pb while writing file
*/
@Override
public void generateFromClass(Writer output, ObjectModelClass input)
throws IOException {
if (isVerbose()) {
log.info("Will generate class "+ input.getQualifiedName());
}
preparePrefix(input);
// Imports, package et documentation
generateHeader(output, input);
String abstractStr = input.isAbstract() ? " abstract" : "";
String staticStr = input.isStatic() ? " static" : "";
String className = input.getName();
String extend = "";
Iterator j = input.getSuperclasses().iterator();
if (j.hasNext()) {
ObjectModelClassifier p = j.next();
extend += GeneratorUtil.getSimpleName(p.getQualifiedName());
}
String implement = "";
for (Iterator i =
input.getInterfaces().iterator(); i.hasNext();) {
ObjectModelClassifier parentInterface = i.next();
String interfaceName = GeneratorUtil.getSimpleName(
parentInterface.getQualifiedName());
implement += interfaceName;
if (i.hasNext()) {
implement += ", ";
}
}
if (log.isDebugEnabled()) {
log.debug(className+" : super : "+extend+", interfaces : "
+ implement);
}
generateAnnotations(output, input, input);
output.write(""+prefix+"public"+staticStr+""+abstractStr+" class "+className+"");
/*
* Définition de la super classe : il ne doit y avoir qu'une
*/
if (extend.length() > 0) {
output.write(" extends "+extend+"");
}
if (implement.length() > 0) {
output.write(" implements "+implement+"");
}
output.write(" {\n");
output.write("");
generateInnerClassifiers(output, input.getInnerClassifiers());
preparePrefix(input);
generateAttributes(output, input, input.getAttributes());
generateOperations(output, input, input.getOperations());
output.write(""+prefix+"} //"+className+"\n");
output.write("");
}
@Override
public void generateFromInterface(Writer output,
ObjectModelInterface input)
throws IOException {
if (isVerbose()) {
log.info("Will generate interface "+ input.getQualifiedName());
}
preparePrefix(input);
// Imports, package et documentation
generateHeader(output, input);
String interfaceName = input.getName();
String extend = "";
Iterator j = input.getInterfaces().iterator();
while (j.hasNext()) {
ObjectModelClassifier p = j.next();
extend += GeneratorUtil.getSimpleName(p.getQualifiedName());
if (j.hasNext()) {
extend += ", ";
}
}
generateAnnotations(output, input, input);
output.write(""+prefix+"public interface "+interfaceName+"");
/*
* Définition de la super interface : il peut y en avoir autant qu'on veut
*/
if (extend.length() > 0) {
output.write(" extends "+extend+"");
}
output.write(" {\n");
output.write("");
generateAttributes(output, input, input.getAttributes());
generateOperations(output, input, input.getOperations());
output.write(""+prefix+"} //"+interfaceName+"\n");
output.write("");
}
public void generateAnnotations(Writer output,
ObjectModelClassifier clazz,
ObjectModelElement element)
throws IOException {
AnnotationsManagerExtension managers = getModel().getExtension(
AnnotationsManagerExtension.OBJECTMODEL_EXTENSION,
AnnotationsManagerExtension.class);
String[] annotations = managers.getAnnotations(clazz,element);
for (String annotation : annotations) {
if (!annotation.trim().startsWith("@")) {
// add @ prefix
annotation = "@" + annotation.trim();
}
if (element instanceof ObjectModelOperation || element instanceof ObjectModelAttribute) {
output.write(""+prefix+"");
annotation = " "+annotation;
}
output.write(""+annotation+"");
if (element instanceof ObjectModelClassifier || element instanceof ObjectModelOperation || element instanceof ObjectModelAttribute) {
output.write("\n");
output.write("");
}
}
}
public void generateFromEnumeration(Writer output,
ObjectModelEnumeration input) throws IOException {
//FIXME tchemit 20100718 I don't understand why having two methods FromEnum and FromEnumeration ?
generateFromEnum(output, input);
}
@Override
public void generateFromEnum(Writer output, ObjectModelEnumeration input)
throws IOException {
if (isVerbose()) {
log.info("Will generate enumeration "+ input.getQualifiedName());
}
preparePrefix(input);
generateHeader(output, input); // Imports, package et documentation
String enumzName = input.getName();
String extend = "";
Iterator j = input.getInterfaces().iterator();
if (j.hasNext()) {
ObjectModelClassifier p = j.next();
extend += GeneratorUtil.getSimpleName(p.getQualifiedName());
}
generateAnnotations(output, input, input);
output.write("\n");
output.write(""+prefix+"public enum "+enumzName+"");
if (extend.length() > 0) {
output.write(" implements "+extend+" {\n");
output.write("");
}
else {
output.write(" {\n");
output.write("");
}
// generation of literal
if (input.getLiterals().isEmpty()) {
output.write(" ; ");
} else {
Iterator i = input.getLiterals().iterator();
while (i.hasNext()) {
String literal = i.next();
output.write(""+prefix+" "+literal+""+(i.hasNext() ? "," : ";")+"\n");
output.write("");
}
}
generateAttributes(output, input, input.getAttributes());
generateOperations(output, input, input.getOperations());
output.write(""+prefix+"} //"+enumzName+"\n");
output.write("");
}
public void generateInnerClassifiers(Writer output,
Collection
innerClassifiers)
throws IOException {
if (innerClassifiers == null || innerClassifiers.isEmpty()) {
return;
}
for (ObjectModelClassifier innerClassifier : innerClassifiers) {
if (innerClassifier.isClass()) {
generateFromClass(output, (ObjectModelClass) innerClassifier);
innerLevel--;
continue;
}
if (innerClassifier.isInterface()) {
generateFromInterface(output, (ObjectModelInterface)
innerClassifier);
innerLevel--;
continue;
}
if (innerClassifier.isEnum()) {
generateFromEnum(output, (ObjectModelEnumeration)
innerClassifier);
innerLevel--;
}
}
}
protected void preparePrefix(ObjectModelClassifier clazz) {
if (!clazz.isInner()) {
innerLevel = 0;
prefix = "";
} else {
innerLevel++;
char[] tmp = new char[innerLevel * 4];
Arrays.fill(tmp, ' ');
prefix = new String(tmp);
}
if (log.isDebugEnabled()) {
log.debug("prefix to use for classifier " +
clazz.getName() + " : [" + prefix + "]");
}
}
/**
* Generate Header for a classifier : Package, Documentation, Imports and Classifier signature.
*
* @param output Writer for generating the java file
* @param classifier Classifier for generate header
* @throws IOException if any pb while writing file
*/
protected void generateHeader(Writer output,
ObjectModelClassifier classifier)
throws IOException {
if (classifier.isInner()) {
return;
}
String packageName = classifier.getPackageName();
output.write("package "+packageName+";\n");
output.write("\n");
output.write("");
// potentiel crash si imports non defini -> IllegalArgumentException on "imports"
ImportsManagerExtension managers = getModel().getExtension(
ImportsManagerExtension.OBJECTMODEL_EXTENSION,
ImportsManagerExtension.class);
List imports = managers.getImports(classifier);
for (String singleImport : imports) {
output.write("import "+singleImport+";\n");
output.write("");
}
if (CollectionUtils.isNotEmpty(imports)) {
output.write("\n");
output.write("");
}
}
/**
* Generate attributes from a collection of ObjectModelAttribute.
*
* @param output Writer for generating the java file
* @param clazz classifier in generation
* @param attributes Collection of ObjectModelAttribute to generate
* @throws IOException if any pb while writing file
*/
protected void generateAttributes(Writer output,ObjectModelClassifier clazz,
Collection
attributes)
throws IOException {
for (ObjectModelAttribute attr : attributes) {
output.write("\n");
output.write("");
String documentation = attr.getDocumentation();
if (StringUtils.isNotEmpty(documentation)) {
output.write(""+prefix+" /**\n");
output.write("");
String[] lines = documentation.split("\n");
for (String line : lines) {
output.write(""+prefix+" * "+line+"\n");
output.write("");
}
output.write(""+prefix+" */\n");
output.write("");
}
generateAnnotations(output, clazz, attr);
String attrName = attr.getName();
String attrVisibility = attr.getVisibility();
String attrType = GeneratorUtil.getSimpleName(attr.getType());
String attrStatic = attr.isStatic() ? "static " : "";
String attrFinal = attr.isFinal() ? "final " : "";
String attrTransient = attr.isTransient() ? "transient " : "";
if (clazz instanceof ObjectModelInterface) {
//tchemit 20100507 no modifier for constants in interfaces
attrStatic = "";
attrFinal = "";
attrTransient = "";
attrVisibility = "";
}
if (StringUtils.isNotEmpty(attrVisibility)) {
attrVisibility += " ";
}
String attrValue = StringUtils.isNotEmpty(attr.getDefaultValue()) ?
// ANO#474 FD-20100408 : Don't do any simplification for
// defaultValue, must be managed when the attribute is added
// to the class in the Transformer.
" = " + attr.getDefaultValue() : "";
// " = " + GeneratorUtil.getSimpleName(attr.getDefaultValue()) : "";
output.write(""+prefix+" "+attrVisibility+""+attrStatic+""+attrFinal+""+attrTransient+""+attrType+" "+attrName+""+attrValue+";\n");
output.write("");
}
}
/**
* Generate operations from a collection of ObjectModelOperation
*
* @param output Writer for generating the java file
* @param clazz classifier in generation
* @param operations Collection of ObjectModelOperation to generate
* @throws IOException if any pb while writing file
*/
protected void generateOperations(Writer output,ObjectModelClassifier clazz,
Collection
operations) throws IOException {
if (!operations.isEmpty()) {
output.write("\n");
output.write("");
}
// Ano #493 : FD-20100412
// Use a boolean to know if the classifier is an interface
// Used to avoid generating visibility not needed for interface
boolean interfacez =
ObjectModelInterface.class.isAssignableFrom(clazz.getClass());
for (ObjectModelOperation op : operations) {
String opName = op.getName();
if (opName == null) {
generateBlock(output, clazz, op);
continue;
}
generateOperationDocumentation(output, op);
generateAnnotations(output, clazz, op);
String opVisibility = !interfacez ? op.getVisibility() : "";
String opStatic = op.isStatic() ? "static " : "";
String opAbstract = op.isAbstract() ? "abstract " : "";
ObjectModelParameter returnParam = op.getReturnParameter();
String opReturn = "";
if (returnParam != null) {
opReturn = GeneratorUtil.getSimpleName(
returnParam.getType()) + " ";
}
if (StringUtils.isNotEmpty(opVisibility)) {
opVisibility += " ";
}
output.write(""+prefix+" "+opVisibility+""+opStatic+""+opAbstract+""+opReturn+""+opName+"(");
String comma = "";
Collection params = op.getParameters();
for (ObjectModelParameter param : params) {
String paramName = param.getName();
String paramType = GeneratorUtil.getSimpleName(param.getType());
output.write(""+comma+""+paramType+" "+paramName+"");
comma = ", ";
}
output.write(")");
comma = " throws ";
Set exceptions = op.getExceptions();
for (String exception : exceptions) {
String exceptionName = GeneratorUtil.getSimpleName(exception);
output.write(""+comma+""+exceptionName+"");
comma = ", ";
}
// tchemit 2010-08-14 fix http://www.nuiton.org/issues/show/809
// if (!op.getBodyCode().isEmpty()) {
if (!(clazz instanceof ObjectModelInterface) && !op.isAbstract()) {
String body = op.getBodyCode() == null ? "" : op.getBodyCode();
output.write(""+prefix+" {"+body+""+prefix+"}\n");
output.write("\n");
output.write("");
} else {
output.write(";\n");
output.write("\n");
output.write("");
}
}
}
protected void generateOperationDocumentation(Writer output,
ObjectModelOperation op) throws IOException {
String documentation = op.getDocumentation();
if (StringUtils.isEmpty(documentation)) {
// no documentation for this operation
return;
}
output.write(""+prefix+" /**\n");
output.write(""+prefix+"");
String[] documentationLines = documentation.split("\n");
for (String documentationLine : documentationLines) {
output.write(""+prefix+" * "+documentationLine+"\n");
output.write("");
}
Collection params = op.getParameters();
for (ObjectModelParameter param : params) {
String paramName = param.getName();
String paramDocumentation = param.getDocumentation();
if (paramDocumentation == null) {
paramDocumentation = "";
}
output.write(""+prefix+" * @param "+paramName+" "+paramDocumentation+"\n");
output.write("");
}
ObjectModelParameter returnParam = op.getReturnParameter();
String opReturn = "";
if (returnParam != null) {
opReturn = GeneratorUtil.getSimpleName(
returnParam.getType()) + " ";
if (!opReturn.contains("void")) {
String paramDocumentation = returnParam.getDocumentation();
if (paramDocumentation == null) {
paramDocumentation = "";
}
output.write(""+prefix+" * @return "+paramDocumentation+"\n");
output.write("");
}
}
Set exceptions = op.getExceptions();
for (String exception : exceptions) {
String exceptionName = GeneratorUtil.getSimpleName(exception);
output.write(""+prefix+" * @throws "+exceptionName+"\n");
output.write("");
}
output.write(""+prefix+" */\n");
output.write("");
}
protected void generateBlock(Writer output,
ObjectModelClassifier clazz,
ObjectModelOperation op) throws IOException {
String opStatic = op.isStatic() ? "static " : " ";
output.write(""+prefix+" "+opStatic+"{\n");
output.write(""+prefix+" "+op.getBodyCode()+"\n");
output.write(""+prefix+" }\n");
output.write("\n");
output.write("");
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy