r1242 - in trunk: eugene/src/main/java/org/nuiton/eugene/models/object eugene/src/main/java/org/nuiton/eugene/models/object/reader eugene/src/main/java/org/nuiton/eugene/writer eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/writer
Author: tchemit Date: 2013-05-04 13:25:19 +0200 (Sat, 04 May 2013) New Revision: 1242 Url: http://nuiton.org/projects/eugene/repository/revisions/1242 Log: refs #2681: Make possible to apply templates to different inputs Added: trunk/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/writer/XmlModelChainedFileWriter.java trunk/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/writer/YamlModelChainedFileWriter.java trunk/eugene/src/main/java/org/nuiton/eugene/models/object/reader/ trunk/eugene/src/main/java/org/nuiton/eugene/models/object/reader/AbstractObjectModelReader.java trunk/eugene/src/main/java/org/nuiton/eugene/models/object/reader/XmlObjectModelReader.java trunk/eugene/src/main/java/org/nuiton/eugene/models/object/reader/YamlObjectModelReader.java trunk/eugene/src/main/java/org/nuiton/eugene/models/object/reader/package-info.java trunk/eugene/src/main/java/org/nuiton/eugene/writer/ChainedFileWriterToMemoryModel.java Modified: trunk/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/GenerateMojo.java trunk/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/writer/ModelChainedFileWriter.java trunk/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/writer/XmiChainedFileWriter.java trunk/eugene/src/main/java/org/nuiton/eugene/models/object/ObjectModelReader.java Modified: trunk/eugene/src/main/java/org/nuiton/eugene/models/object/ObjectModelReader.java =================================================================== --- trunk/eugene/src/main/java/org/nuiton/eugene/models/object/ObjectModelReader.java 2013-05-02 14:39:36 UTC (rev 1241) +++ trunk/eugene/src/main/java/org/nuiton/eugene/models/object/ObjectModelReader.java 2013-05-04 11:25:19 UTC (rev 1242) @@ -32,6 +32,7 @@ import org.nuiton.eugene.EugeneTagValues; import org.nuiton.eugene.ModelPropertiesUtil; import org.nuiton.eugene.ModelReader; +import org.nuiton.eugene.models.object.reader.XmlObjectModelReader; import org.nuiton.eugene.models.object.xml.DigesterObjectModelRuleSet; import org.nuiton.eugene.models.object.xml.ObjectModelAssociationClassImpl; import org.nuiton.eugene.models.object.xml.ObjectModelClassifierImpl; @@ -63,7 +64,9 @@ * @author fdesbois <fdesbois@codelutin.com> * @version $Id$ * @plexus.component role="org.nuiton.eugene.ModelReader" role-hint="objectmodel" + * @deprecated since 2.6.3, is replaced by {@link XmlObjectModelReader}. */ +@Deprecated public class ObjectModelReader extends ModelReader<ObjectModel> { private static final Log log = LogFactory.getLog(ObjectModelReader.class); Added: trunk/eugene/src/main/java/org/nuiton/eugene/models/object/reader/AbstractObjectModelReader.java =================================================================== --- trunk/eugene/src/main/java/org/nuiton/eugene/models/object/reader/AbstractObjectModelReader.java (rev 0) +++ trunk/eugene/src/main/java/org/nuiton/eugene/models/object/reader/AbstractObjectModelReader.java 2013-05-04 11:25:19 UTC (rev 1242) @@ -0,0 +1,579 @@ +package org.nuiton.eugene.models.object.reader; + +/* + * #%L + * EUGene :: EUGene + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2013 CodeLutin + * %% + * 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 + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.eugene.EugeneTagValues; +import org.nuiton.eugene.ModelPropertiesUtil; +import org.nuiton.eugene.ModelReader; +import org.nuiton.eugene.models.object.ObjectModel; +import org.nuiton.eugene.models.object.ObjectModelAssociationClass; +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.ObjectModelOperation; +import org.nuiton.eugene.models.object.xml.ObjectModelAssociationClassImpl; +import org.nuiton.eugene.models.object.xml.ObjectModelClassifierImpl; +import org.nuiton.eugene.models.object.xml.ObjectModelElementImpl; +import org.nuiton.eugene.models.object.xml.ObjectModelImpl; +import org.nuiton.eugene.models.object.xml.ObjectModelImplRef; +import org.nuiton.util.FileUtil; +import org.nuiton.util.RecursiveProperties; +import org.nuiton.util.StringUtil; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * TODO + * + * @author tchemit <chemit@codelutin.com> + * @since TODO + */ +public abstract class AbstractObjectModelReader extends ModelReader<ObjectModel> { + + private static final Log log = LogFactory.getLog(AbstractObjectModelReader.class); + + public static final String TAGVALUE = "tagvalue"; + + public static final String STEREOTYPE = "stereotype"; + + public static final String OPERATION = "operation"; + + public static final String ATTRIBUTE = "attribute"; + + public static final String CLASS = "class"; + + /** + * Pattern to define tag values authorized at classifier level in the model + * properties file. + * <p/> + * L'expression réguliere match les chaines de type + * <package.ClassName>.<class|attribute|operation>.[name].<stereotype|tagvalue>.[tag] + * fr.isisfish.entities.Population.class.stereotype=entity + * fr.isisfish.entities.Population.class.tagvalue.persistenceType=flatfile + * fr.isisfish.entities.Population.attribute.name.stereotype=... + * fr.isisfish.entities.Population.attribute.name.tagvalue.pk=topiaId + * fr.isisfish.entities.Population.operation.getRegion.stereotype=... + * fr.isisfish.entities.Population.operation.getRegion.tagvalue.pk=... + */ + protected Pattern propertiesPattern = Pattern + .compile("^((?:[_a-zA-Z0-9]+\\.)+(?:_?[A-Z][_a-zA-Z0-9]*\\.)+)(?:(class|attribute|operation))\\.(?:([_a-zA-Z0-9]+)\\.)?(?:(tagvalue|tagValue)?)\\.([_a-z0-9][_a-zA-Z0-9]*)?$"); + + protected Pattern stereotypePattern = Pattern + .compile("^((?:[_a-zA-Z0-9]+\\.)+(?:_?[A-Z][_a-zA-Z0-9]*\\.)+)(?:(class|attribute|operation))\\.(?:([_a-zA-Z0-9]+)\\.)?(?:(stereotype)?)$"); + + /** + * Pattern to define tag values authorized at model level in the model + * properties file. + */ + protected Pattern modelTagValuePattern = Pattern.compile( + "^model\\.(?:(tagvalue|tagValue)?)\\.((?:.+))$"); + + public static final String MODEL = "model"; + + protected abstract void readFileToModel(File file, ObjectModel model) throws IOException; + + protected void beforeReadFile(File... files) { + setLastModifiedSource(files); + if (log.isDebugEnabled()) { + log.debug("LastModifiedSource = " + getLastModifiedSource() + + " for file " + Arrays.toString(files)); + } + + if (modelPropertiesProvider == null) { + if (log.isWarnEnabled()) { + log.warn("No properties provider filled, will instanciate a new default one"); + } + setModelPropertiesProvider(ModelPropertiesUtil.newStore(getClass().getClassLoader(), false)); + } + } + + @Override + public ObjectModel read(File... files) throws IOException { + + beforeReadFile(files); + + ObjectModel model = new ObjectModelImpl(); + + for (File file : files) { + + readFileToModel(file, model); + + // recherche est charge le fichier propriete associe au modele + File dir = file.getParentFile(); + String ext = FileUtil.extension(file); + String name = FileUtil.basename(file, "." + ext); + File propFile = new File(dir, name + ".properties"); + if (!propFile.exists()) { + if (isVerbose()) { + log.info("Pas de fichier de propriete " + propFile + + " associé au model"); + } + } else { + if (isVerbose()) { + log.info("Lecture du fichier de propriete " + propFile + + " associé au model"); + } + loadModelProperties(propFile, model); + } + + } + + + if (log.isDebugEnabled()) { + for (ObjectModelClass m : model.getClasses()) { + log.debug("loaded class in objectmodel : " + m.getName()); + } + } + return model; + } + + /** + * Retrieve an attribute from a {@code clazz} with its {@code name}. + * This method manage the association class case to explore participants + * attributes if needed. + * + * @param clazz where the attribute need to be find + * @param name attribute name to find + * @return the attribute found or null + */ + protected ObjectModelAttribute getAttribute(ObjectModelClass clazz, + String name) { + ObjectModelAttribute result = clazz.getAttribute(name); + + // Ano #619 : FD-2010-05-17 : Specific case for Association class : + // check on participant attributes + if (result == null && clazz instanceof ObjectModelAssociationClassImpl) { + if (log.isDebugEnabled()) { + log.debug("Attribute " + name + " not found from " + + clazz.getQualifiedName() + " association class. " + + "Will check participants..."); + } + ObjectModelAssociationClass assoc = (ObjectModelAssociationClass) clazz; + for (ObjectModelAttribute participant : assoc.getParticipantsAttributes()) { + if (participant.getName().equals(name)) { + result = participant; + break; + } + } + } + return result; + } + + public Properties loadModelProperties(File propFile, + ObjectModel model) throws IOException { + + Properties prop = new RecursiveProperties(); +// try { + FileInputStream inStream = new FileInputStream(propFile); + try { + prop.load(inStream); + } finally { + inStream.close(); + } + + // number of sucessfull imported tag values into model + int numberImportedTagValues = 0; + + // get all the tagvalues keys and sort them + List<String> keys = new ArrayList<String>(); + CollectionUtils.addAll(keys, prop.keys()); + Collections.sort(keys); + + // for each tag value try to import in in model + for (String key : keys) { + String value = prop.getProperty(key); + + if (log.isDebugEnabled()) { + log.debug("Propriete: '" + key + "' = " + value); + } + + if (key.startsWith(MODEL)) { + + // model tag value + + boolean loaded = loadModelTagValue(model, key, value); + + if (loaded) { + + numberImportedTagValues++; + } + continue; + } + + // element tag value or stereotype + + if (key.contains(STEREOTYPE)) { + + // stereotype property + + boolean loaded = loadStereotype(model, key, value); + + if (loaded) { + numberImportedTagValues++; + } + + continue; + + } + + // tag value property + + boolean loaded = loadTagValue(model, key, value); + + if (loaded) { + numberImportedTagValues++; + } + } + if (log.isInfoEnabled()) { + log.info(numberImportedTagValues + " tag values were succesfull imported from " + propFile); + } + int nbFailed = prop.size() - numberImportedTagValues; + if (nbFailed > 0 && isVerbose()) { + log.info(nbFailed + " tag values failed to be imported from " + propFile); + } + return prop; + } + + public boolean loadModelTagValue(ObjectModel model, String key, String value) { + Matcher matcher = modelTagValuePattern.matcher(key); + + if (!matcher.find()) { + if (log.isWarnEnabled()) { + log.warn("Invalid model tag value [" + key + "] : only tagvalue or tagValue is allowed on model in properties"); + } + return false; + } + String tag = matcher.group(2); + + boolean safe = modelPropertiesProvider.containsTagValue(tag); + + if (!safe) { + if (log.isWarnEnabled()) { + log.warn("Invalid model tag value [" + key + "] : the tagvalue '" + tag + "' is unkown."); + } + } else { + safe = modelPropertiesProvider.acceptTagValue(tag, ObjectModel.class); + + if (!safe) { + + // the tag value can not be apply of model + if (log.isWarnEnabled()) { + log.warn("Invalid model tag value [" + key + "] : this tagvalue '" + tag + "' can not be apply on the model."); + } + } + } + + if (!safe && isStrictLoading()) { + + // in strict loading do not accept unsafe tags + return false; + } + + ObjectModelImpl modelImpl = (ObjectModelImpl) model; + if (tag.equals(EugeneTagValues.TAG_VERSION)) { + + // push directly the version in the model version + // property + modelImpl.setVersion(value); + } + if (isVerbose()) { + log.info("model tag value imported " + key + " --> " + tag + " = " + value); + } + modelImpl.addTagValue(tag, value); + return true; + } + + public boolean loadStereotype(ObjectModel model, String key, String value) { + Matcher matcher = stereotypePattern.matcher(key); + + if (!matcher.find()) { + + if (log.isWarnEnabled()) { + log.warn("Invalid stereotype [" + key + "] : syntax is not correct."); + } + return false; + } + + String fqn = matcher.group(1); + fqn = StringUtil.substring(fqn, 0, -1); // remove ended . + // target is class, attribute or operation + String target = matcher.group(2); + String targetName = matcher.group(3); + // type is stereotype + String type = matcher.group(4).toLowerCase(); + // target real type + Class<?> targetType = getTargetType(target); + + boolean safe = modelPropertiesProvider.containsStereotype(value); + + if (!safe) { + + // stereotype unkown + if (log.isWarnEnabled()) { + log.warn("Invalid stereotype [" + key + "] : this stereotype '" + value + "' is unkown."); + } + } else { + + safe = modelPropertiesProvider.acceptStereotype(value, targetType); + + if (!safe) { + + // the stereotype can not be apply of the given target + if (log.isWarnEnabled()) { + log.warn("Invalid stereotype [" + key + "] : this stereotype '" + value + "' can not be apply on " + target + "."); + } + } + } + + if (!safe && isStrictLoading()) { + + // in strict loading do not accept unsafe stereotypes + return false; + } + + if (log.isDebugEnabled()) { + log.debug("Propriete: '" + key + "' => " + + "fqn:" + fqn + " target:" + target + + " targetName:" + targetName + + " type:" + type); + } + + ObjectModelClassifier omc = getClassifier(model, STEREOTYPE, key, fqn); + if (omc == null) { + + // classifier not found + return false; + } + + List<ObjectModelElement> elems = getObjectElements(omc, STEREOTYPE, key, fqn, target, targetName); + + if (elems == null) { + + // no element to apply + return false; + } + + for (ObjectModelElement elem1 : elems) { + //TODO tchemit 2010-11-29 uncomment this if there is some proble, but I don't see why there would be... +// if (elem1 == null) { +// if (log.isWarnEnabled()) { +// log.warn("Invalid stereotype [" + key + "] : Element '" + targetName + "' of type '" + target + "' on classifier '" + fqn + "' is null."); +// } +// continue; +// } + ObjectModelElementImpl elem = (ObjectModelElementImpl) elem1; + + // pour les stereotypes + ObjectModelImplRef stereotype = new ObjectModelImplRef(); + stereotype.setName(value); + elem.addStereotype(stereotype); + } + + if (isVerbose()) { + log.info("stereotype imported " + key + " --> " + fqn + ":" + target + ":" + targetName + ":" + type + " = " + value); + } + + return true; + } + + private boolean loadTagValue(ObjectModel model, String key, String value) { + Matcher matcher = propertiesPattern.matcher(key); + + if (!matcher.find()) { + + if (log.isWarnEnabled()) { + log.warn("Invalid tag value [" + key + "] : syntax is not correct."); + } + return false; + } + + String fqn = matcher.group(1); + fqn = StringUtil.substring(fqn, 0, -1); // remove ended + // . + // target is class, attribute or operation + String target = matcher.group(2); + // name of the target (can be null on class) + String targetName = matcher.group(3); + // type is tagvalue + String type = matcher.group(4).toLowerCase(); + // name of the tag value + String tag = matcher.group(5); + // target real type + Class<?> targetType = getTargetType(target); + + if (log.isDebugEnabled()) { + log.debug("Propriete: '" + key + "' => " + + "fqn:" + fqn + " target:" + target + + " targetName:" + targetName + + " type:" + type + " tag:" + tag); + } + + boolean safe = modelPropertiesProvider.containsTagValue(tag); + + if (!safe) { + + // unkown tag value + if (log.isWarnEnabled()) { + log.warn("Invalid tag value [" + key + "] : this tagvalue '" + tag + "' is unkown."); + } + } else { + + safe = modelPropertiesProvider.acceptTagValue(tag, targetType); + + if (!safe) { + + // the tag value can not be apply of model + if (log.isWarnEnabled()) { + log.warn("Invalid tag value [" + key + "] : this tagvalue '" + tag + "' can not be apply on the given type '" + target + "'."); + } + } + } + + if (!safe && isStrictLoading()) { + + // in strict loading do not accept unsafe tags + return false; + } + + ObjectModelClassifier omc = getClassifier(model, TAGVALUE, key, fqn); + if (omc == null) { + + // classifier not found + return false; + } + + List<ObjectModelElement> elements = + getObjectElements(omc, TAGVALUE, key, fqn, target, targetName); + + if (elements == null) { + + // no elements to apply + return false; + } + + for (ObjectModelElement element : elements) { + + if (log.isDebugEnabled()) { + log.debug("add tagValue " + tag + + ", value:" + value + + " to element:" + element); + } + ((ObjectModelElementImpl) element).addTagValue(tag, value); + + } + if (isVerbose()) { + log.info("tag value imported " + key + " --> " + fqn + ":" + target + ":" + targetName + ":" + type + ":" + tag + " = " + value); + } + return true; + } + + protected Class<?> getTargetType(String target) { + Class<?> result = null; + if (ATTRIBUTE.equals(target)) { + return ObjectModelAttribute.class; + } + if (OPERATION.equals(target)) { + return ObjectModelOperation.class; + } + if (CLASS.equals(target)) { + return ObjectModelClassifier.class; + } + + return result; + } + + protected ObjectModelClassifier getClassifier(ObjectModel model, String type, String key, String fqn) { + ObjectModelClassifier omc = model.getClassifier(fqn); + if (omc == null) { + if (log.isWarnEnabled()) { + log.warn("Invalid " + type + " [" + key + + "] : Could not find classifier for " + fqn); + } + return null; + } + + //todo tchemit 2010-11-25 : what does it mean ? every thing extends ObjectModelClassifierImpl + if (!(omc instanceof ObjectModelClassifierImpl)) { + // TODO il faudra avoir des methodes d'acces en Set sur l'interface pour eviter ce message + if (log.isWarnEnabled()) { + log.warn("Can't add properties to model, " + + "it's not an " + + "ObjectModelClassifierImpl : " + + omc.getQualifiedName()); + } + return null; + } + return omc; + } + + protected List<ObjectModelElement> getObjectElements(ObjectModelClassifier omc, String type, String key, String fqn, String target, String targetName) { + List<ObjectModelElement> elems = new ArrayList<ObjectModelElement>(); + if (CLASS.equals(target)) { + elems.add(omc); + } else if (ATTRIBUTE.equals(target)) { + + ObjectModelAttribute attr = + getAttribute((ObjectModelClass) omc, targetName); + elems.add(attr); + + } else if (OPERATION.equals(target)) { + elems.addAll(omc.getOperations(targetName)); + } + + if (elems.isEmpty()) { + if (log.isWarnEnabled()) { + log.warn("Invalid " + type + " [" + key + "] : Could not find any element '" + targetName + "' of type '" + target + "' on classifier '" + fqn + "'."); + } + return null; + } + + Iterator<ObjectModelElement> itr = elems.iterator(); + while (itr.hasNext()) { + ObjectModelElement element = itr.next(); + if (element == null) { + if (log.isWarnEnabled()) { + log.warn("Invalid " + type + " [" + key + "] : Element '" + targetName + "' of type '" + target + "' on classifier '" + fqn + "' is null."); + } + itr.remove(); + } + } + + return elems; + } +} Property changes on: trunk/eugene/src/main/java/org/nuiton/eugene/models/object/reader/AbstractObjectModelReader.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Copied: trunk/eugene/src/main/java/org/nuiton/eugene/models/object/reader/XmlObjectModelReader.java (from rev 1239, trunk/eugene/src/main/java/org/nuiton/eugene/models/object/ObjectModelReader.java) =================================================================== --- trunk/eugene/src/main/java/org/nuiton/eugene/models/object/reader/XmlObjectModelReader.java (rev 0) +++ trunk/eugene/src/main/java/org/nuiton/eugene/models/object/reader/XmlObjectModelReader.java 2013-05-04 11:25:19 UTC (rev 1242) @@ -0,0 +1,65 @@ +/* + * #%L + * EUGene :: EUGene + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2012 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 + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +package org.nuiton.eugene.models.object.reader; + +import org.apache.commons.digester3.Digester; +import org.nuiton.eugene.models.object.ObjectModel; +import org.nuiton.eugene.models.object.xml.DigesterObjectModelRuleSet; +import org.nuiton.eugene.models.object.xml.ObjectModelImpl; +import org.xml.sax.SAXException; + +import java.io.File; +import java.io.IOException; + +/** + * To read object xml model files into an memory object model. + * + * @author tchemit <chemit@codelutin.com> + * @plexus.component role="org.nuiton.eugene.ModelReader" role-hint="xmlobjectmodel" + * @since 2.6.3 + */ +public class XmlObjectModelReader extends AbstractObjectModelReader { + + protected Digester digester; + + @Override + protected void beforeReadFile(File... files) { + super.beforeReadFile(files); + digester = new Digester(); + digester.addRuleSet(new DigesterObjectModelRuleSet()); + } + + @Override + protected void readFileToModel(File file, ObjectModel model) throws IOException { + try { + digester.push(new ObjectModelImpl()); + digester.parse(file); + } catch (SAXException e) { + throw new IOException("Unable to parse ObjectModel input file : " + file, e); + } + } + +} Added: trunk/eugene/src/main/java/org/nuiton/eugene/models/object/reader/YamlObjectModelReader.java =================================================================== --- trunk/eugene/src/main/java/org/nuiton/eugene/models/object/reader/YamlObjectModelReader.java (rev 0) +++ trunk/eugene/src/main/java/org/nuiton/eugene/models/object/reader/YamlObjectModelReader.java 2013-05-04 11:25:19 UTC (rev 1242) @@ -0,0 +1,58 @@ +package org.nuiton.eugene.models.object.reader; + +/* + * #%L + * EUGene :: EUGene + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2013 CodeLutin + * %% + * 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 + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.eugene.models.object.ObjectModel; + +import java.io.File; +import java.io.IOException; + +/** + * To read object model from yaml files into an memory object model. + * + * @author tchemit <chemit@codelutin.com> + * @plexus.component role="org.nuiton.eugene.ModelReader" role-hint="yamlobjectmodel" + * @since 2.6.3 + */ +public class YamlObjectModelReader extends AbstractObjectModelReader { + + private static final Log log = + LogFactory.getLog(YamlObjectModelReader.class); + + @Override + protected void beforeReadFile(File... files) { + super.beforeReadFile(files); + //TODO ? + } + + @Override + protected void readFileToModel(File file, + ObjectModel model) throws IOException { + //TODO + } + +} Property changes on: trunk/eugene/src/main/java/org/nuiton/eugene/models/object/reader/YamlObjectModelReader.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/eugene/src/main/java/org/nuiton/eugene/models/object/reader/package-info.java =================================================================== --- trunk/eugene/src/main/java/org/nuiton/eugene/models/object/reader/package-info.java (rev 0) +++ trunk/eugene/src/main/java/org/nuiton/eugene/models/object/reader/package-info.java 2013-05-04 11:25:19 UTC (rev 1242) @@ -0,0 +1,32 @@ +/* + * #%L + * EUGene :: EUGene + * * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2010 CodeLutin + * %% + * 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 + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +/** + * Eugene object model reader package. + * + * @since 2.6.3 + */ +package org.nuiton.eugene.models.object.reader; + Property changes on: trunk/eugene/src/main/java/org/nuiton/eugene/models/object/reader/package-info.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: trunk/eugene/src/main/java/org/nuiton/eugene/writer/ChainedFileWriterToMemoryModel.java =================================================================== --- trunk/eugene/src/main/java/org/nuiton/eugene/writer/ChainedFileWriterToMemoryModel.java (rev 0) +++ trunk/eugene/src/main/java/org/nuiton/eugene/writer/ChainedFileWriterToMemoryModel.java 2013-05-04 11:25:19 UTC (rev 1242) @@ -0,0 +1,62 @@ +package org.nuiton.eugene.writer; + +/* + * #%L + * EUGene :: EUGene + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2004 - 2013 CodeLutin + * %% + * 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 + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.nuiton.eugene.models.Model; + +import java.io.File; + +/** + * Contract to define a specialized {@link ChainedFileWriter} which generate + * no files but a memory model. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.6.3 + */ +public interface ChainedFileWriterToMemoryModel extends ChainedFileWriter { + + /** + * Reads inputs files and load them in a unique memory model. + * + * @return the memory model loaded from input files. + */ + Model getModel(); + + /** + * Gets the latest last modified time of physicial files used to load + * the memory model. + * + * @return the latest last modified of any files used to load memory model. + */ + long getLastModifiedSource(); + + /** + * Gets the directory where to generate later files froma pplying template + * to this memory model. + * + * @return where to generate files from this model. + */ + File getOutputDirectory(); +} Property changes on: trunk/eugene/src/main/java/org/nuiton/eugene/writer/ChainedFileWriterToMemoryModel.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: trunk/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/GenerateMojo.java =================================================================== --- trunk/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/GenerateMojo.java 2013-05-02 14:39:36 UTC (rev 1241) +++ trunk/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/GenerateMojo.java 2013-05-04 11:25:19 UTC (rev 1242) @@ -43,10 +43,13 @@ import org.nuiton.eugene.plugin.writer.BaseChainedFileWriter; import org.nuiton.eugene.plugin.writer.ModelChainedFileWriter; import org.nuiton.eugene.plugin.writer.XmiChainedFileWriter; +import org.nuiton.eugene.plugin.writer.XmlModelChainedFileWriter; +import org.nuiton.eugene.plugin.writer.YamlModelChainedFileWriter; import org.nuiton.eugene.writer.ChainedFileWriter; import org.nuiton.eugene.writer.ChainedFileWriterConfiguration; import org.nuiton.eugene.writer.ChainedFileWriterData; import org.nuiton.eugene.writer.ChainedFileWriterEntry; +import org.nuiton.eugene.writer.ChainedFileWriterToMemoryModel; import org.nuiton.eugene.writer.ChainedWriterEngine; import org.nuiton.eugene.writer.WriterReport; import org.nuiton.plugin.AbstractPlugin; @@ -54,6 +57,7 @@ import org.nuiton.util.StringUtil; import java.io.File; +import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; @@ -63,6 +67,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Properties; import java.util.Set; /** @@ -325,6 +330,24 @@ /** fixed classloader */ protected ClassLoader fixedClassLoader; + protected List<Template<Model>> templateList; + + protected WriterReport newWriterReport() { + WriterReport writerReport = new WriterReport() { + @Override + public void addFile(String entry, File file, boolean b) { + super.addFile(entry, file, b); + if (b || isVerbose()) { + getLog().info("Will generate " + file); + } + if (getLog().isDebugEnabled()) { + getLog().debug(String.format("[%1$s] Will generate %2$s", entry, file)); + } + } + }; + return writerReport; + } + @Override protected void init() throws Exception { @@ -365,18 +388,7 @@ // add log support ((BaseChainedFileWriter) writer).setLog(getLog()); } - writer.setWriterReport(new WriterReport() { - @Override - public void addFile(String entry, File file, boolean b) { - super.addFile(entry, file, b); - if (b || isVerbose()) { - getLog().info("Will generate " + file); - } - if (getLog().isDebugEnabled()) { - getLog().debug(String.format("[%1$s] Will generate %2$s", entry, file)); - } - } - }); + writer.setWriterReport(newWriterReport()); } // detect top level writers @@ -429,6 +441,25 @@ properties.put(ModelChainedFileWriter.PROP_TEMPLATE_CONFIGURATION, configuration); } + + if (engine.containsWriter("xmlmodel")) { + + // add xml model writer support + + properties.put(XmlModelChainedFileWriter.PROP_MODEL_PROPERTIES_PROVIDER, + getModelPropertiesProvider()); + } + + if (engine.containsWriter("yamlmodel")) { + + // add yaml model writer support + + properties.put(YamlModelChainedFileWriter.PROP_MODEL_PROPERTIES_PROVIDER, + getModelPropertiesProvider()); + } + + // init templates + templateList = initTemplates(); } @Override @@ -463,6 +494,8 @@ // launch writers in incoming order of dicovering of them + Set<ChainedFileWriterToMemoryModel> models = new HashSet<ChainedFileWriterToMemoryModel>(); + for (ChainedFileWriter writer : engine.getSelectedWriters()) { if (skipInputList.contains(writer.getInputProtocol())) { getLog().info("Skip phase [" + writer.getInputProtocol() + @@ -498,6 +531,12 @@ // launch generation writer.generate(this, data); + if (writer instanceof ChainedFileWriterToMemoryModel) { + // keep result + ChainedFileWriterToMemoryModel writerToMemoryModel = (ChainedFileWriterToMemoryModel) writer; + + models.add(writerToMemoryModel); + } String message = reportGeneratedFiles(writer, t0); getLog().info(message); @@ -511,6 +550,19 @@ } } + // merge all models in a unique one ? or apply templates on each model ? + + WriterReport writerReport = newWriterReport(); + + for (ChainedFileWriterToMemoryModel entry : models) { + Model model = entry.getModel(); + Long lastModified = entry.getLastModifiedSource(); + File outputDirectory = entry.getOutputDirectory(); + + applyTemplates(model, lastModified, outputDirectory, templateList, writerReport); + } + + } finally { // always clear everything to avoid side-effects in goal is // invoked more than once @@ -519,7 +571,34 @@ } } + protected void applyTemplates(Model model, + Long lastModifiedSource, + File outputDirectory, + List<Template<Model>> templateList, + WriterReport writerReport) throws IOException { + for (Template<Model> template : templateList) { + getLog().info("Apply generator " + template.getClass().getSimpleName()); + + // set the lastModified source property + template.setProperty(Template.PROP_LAST_MODIFIED_SOURCE, lastModifiedSource); + + template.setProperty(Template.PROP_WRITER_REPORT, writerReport); + + if (isVerbose()) { + getLog().info(" overwrite = " + template.isOverwrite()); + getLog().info(" encoding = " + template.getEncoding()); + getLog().info(" lastModifiedSource = " + template.getLastModifiedSource()); + getLog().info(" exclude = " + template.getExcludeTemplates()); + getLog().info(" output directory = " + outputDirectory); + } + + // apply template + template.applyTemplate(model, outputDirectory); + } + } + + public String reportGeneratedFiles(ChainedFileWriter writer, long t0) { WriterReport writerReport = writer.getWriterReport(); int nbFiles = writerReport.getFilesCount(); @@ -859,4 +938,74 @@ } return provider; } + + protected List<Template<Model>> initTemplates() { + + ChainedFileWriterConfiguration configuration = this; + + ClassLoader loader = configuration.getClassLoader(); + + boolean verbose = configuration.isVerbose(); + + Properties templateProperties = new Properties(); + + templateProperties.put(Template.PROP_DEFAULT_PACKAGE, defaultPackage); + templateProperties.put(Template.PROP_ENCODING, configuration.getEncoding()); + templateProperties.put(Template.PROP_VERBOSE, verbose); + templateProperties.put(Template.PROP_OVERWRITE, configuration.isOverwrite()); + templateProperties.put(Template.PROP_CLASS_LOADER, loader); + templateProperties.put(Template.PROP_EXCLUDE_TEMPLATES, excludeTemplates); + + + if (StringUtils.isEmpty(generatedPackages)) { + if (verbose) { + getLog().info("generating all packages"); + } + } else { + templateProperties.put(Template.PROP_GENERATED_PACKAGES, + generatedPackages); + if (verbose) { + getLog().info("generating only for packages " + generatedPackages); + } + } + + // init templates + + List<Template<Model>> templatesList = new ArrayList<Template<Model>>(); + if (StringUtils.isEmpty(templates)) { + throw new IllegalArgumentException("No template specified, use the templates parameter"); + } + String[] templatesNames = templates.split(","); + for (String templateName : templatesNames) { + // remove trailing spaces + templateName = templateName.trim(); + Template<Model> template = + (Template<Model>) configuration.getModelTemplates().get(templateName); + + if (template == null) { + getLog().warn("template [" + templateName + "] is not " + + "registred via plexus, try to load it directly"); + try { + template = (Template<Model>) Class.forName( + templateName, true, loader).newInstance(); + } catch (Exception e) { + throw new IllegalStateException( + "Can't obtain template [" + templateName + + "] for reason " + e.getMessage(), e); + } + } + + if (verbose) { + getLog().info("will use the template [" + templateName + "]"); + } + + // will use this template + templatesList.add(template); + + // set the properties of the template + template.setConfiguration( + new DefaultTemplateConfiguration(templateProperties)); + } + return templatesList; + } } Modified: trunk/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/writer/ModelChainedFileWriter.java =================================================================== --- trunk/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/writer/ModelChainedFileWriter.java 2013-05-02 14:39:36 UTC (rev 1241) +++ trunk/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/writer/ModelChainedFileWriter.java 2013-05-04 11:25:19 UTC (rev 1242) @@ -47,7 +47,6 @@ * To write model files from zargo files. * * @author tchemit - * @plexus.component role="org.nuiton.eugene.writer.ChainedFileWriter" role-hint="model2Java" * @since 2.0.0 */ public class ModelChainedFileWriter extends BaseChainedFileWriter { @@ -219,7 +218,18 @@ // set the verbose level of the model reader getModelReader().setVerbose(verbose); - + + List<Template<?>> templatesList = initTemplates(configuration); + + properties.put(PROP_TEMPLATES_LIST, templatesList); + } + + protected List<Template<?>> initTemplates(ChainedFileWriterConfiguration configuration) { + + ClassLoader loader = configuration.getClassLoader(); + + boolean verbose = configuration.isVerbose(); + Properties templateProperties = new Properties(); templateProperties.put(Template.PROP_DEFAULT_PACKAGE, getDefaultPackage()); @@ -279,8 +289,7 @@ template.setConfiguration( new DefaultTemplateConfiguration(templateProperties)); } - - properties.put(PROP_TEMPLATES_LIST, templatesList); + return templatesList; } @Override Modified: trunk/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/writer/XmiChainedFileWriter.java =================================================================== --- trunk/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/writer/XmiChainedFileWriter.java 2013-05-02 14:39:36 UTC (rev 1241) +++ trunk/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/writer/XmiChainedFileWriter.java 2013-05-04 11:25:19 UTC (rev 1242) @@ -94,7 +94,7 @@ @Override public String getOutputProtocol(String modelType) { // next writer : write from model files - return "model"; + return "xmlmodel"; } @Override Copied: trunk/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/writer/XmlModelChainedFileWriter.java (from rev 1239, trunk/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/writer/ModelChainedFileWriter.java) =================================================================== --- trunk/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/writer/XmlModelChainedFileWriter.java (rev 0) +++ trunk/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/writer/XmlModelChainedFileWriter.java 2013-05-04 11:25:19 UTC (rev 1242) @@ -0,0 +1,224 @@ +/* + * #%L + * EUGene :: Maven plugin + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2006 - 2010 CodeLutin + * %% + * 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 + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +package org.nuiton.eugene.plugin.writer; + +import org.nuiton.eugene.ModelPropertiesUtil; +import org.nuiton.eugene.ModelReader; +import org.nuiton.eugene.models.Model; +import org.nuiton.eugene.writer.ChainedFileWriterConfiguration; +import org.nuiton.eugene.writer.ChainedFileWriterToMemoryModel; + +import java.io.File; +import java.io.IOException; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * To create a memory model from xml model files. + * + * @author tchemit + * @plexus.component role="org.nuiton.eugene.writer.ChainedFileWriter" role-hint="xmlModel2Memory" + * @since 2.6.3 + */ +public class XmlModelChainedFileWriter extends BaseChainedFileWriter implements ChainedFileWriterToMemoryModel { + + public static final String PROP_XML_MODEL_READER = "xmlModelReader"; + + public static final String PROP_MODEL_PROPERTIES_PROVIDER = "modelPropertiesProvider"; + + public static final String PROP_READER = "reader"; + + protected Model model; + + protected long lastModifiedSource; + + protected File outputDirectory; + + public XmlModelChainedFileWriter() { + super( + PROP_READER, "reader", + PROP_XML_MODEL_READER, "modelReader", + PROP_MODEL_PROPERTIES_PROVIDER, "modelPropertiesProvider" + ); + } + + @Override + public Model getModel() { + return model; + } + + public long getLastModifiedSource() { + return lastModifiedSource; + } + + @Override + public File getOutputDirectory() { + return outputDirectory; + } + + @Override + public String getInputProtocol() { + return "xmlmodel"; + } + + @Override + public String getOutputProtocol(String modelType) { + // nothing after java files + //TODO check in engine that a memory chained file has null output protocol + return null; + } + + @Override + public boolean acceptModel(String modelType) { + // accept all models + return acceptObjectModelOrStateModel(modelType); + } + + @Override + public boolean acceptInclude(String include) { + return include.startsWith("model:") || + include.endsWith(".objectmodel") || + include.endsWith(".statemodel"); + } + + @Override + public String getDefaultIncludes() { + return "**/*.*model"; + } + + @Override + public String getDefaultInputDirectory() { + return "src/main/models"; + } + + @Override + public String getDefaultOutputDirectory() { + return "java"; + } + + @Override + public String getDefaultTestInputDirectory() { + return "src/test/models"; + } + + @Override + public String getDefaultTestOutputDirectory() { + return "test-java"; + } + + protected ModelReader<?> getModelReader() { + return getProperty(PROP_XML_MODEL_READER, ModelReader.class); + } + + protected String getReader() { + return getProperty(PROP_READER, String.class); + } + + protected ModelPropertiesUtil.ModelPropertiesProvider getModelPropertiesProvider() { + return getProperty(PROP_MODEL_PROPERTIES_PROVIDER, ModelPropertiesUtil.ModelPropertiesProvider.class); + } + + @Override + protected void initWriter(ChainedFileWriterConfiguration configuration) { + super.initWriter(configuration); + + // obtain a reader + ClassLoader classLoader = configuration.getClassLoader(); + ClassLoader loader = classLoader; + if (getModelReader() == null) { + + if (getReader() != null) { + // use a specific reader + String reader = getReader(); + try { + ClassLoader fixedClassLoader = loader; + ModelReader<?> modelReader = (ModelReader<?>) + Class.forName(reader, true, + fixedClassLoader).newInstance(); + //TODO : should check that the reader is compatible with + //TODO : given modelType + properties.put(PROP_XML_MODEL_READER, modelReader); + } catch (Exception eee) { + throw new IllegalStateException("could not obtain reader " + + reader, eee); + } + } else { + String modelType = configuration.getModelType(); + ModelReader<?> modelReader = + configuration.getModelReaders().get(modelType); + if (modelReader == null) { + throw new IllegalStateException( + "could not find a model reader for modelType : " + + modelType + ", availables readers : " + + configuration.getModelReaders().values()); + } + properties.put(PROP_XML_MODEL_READER, modelReader); + } + } + + boolean verbose = configuration.isVerbose(); + + // gets the provider of safe tag values and stereotypes + ModelPropertiesUtil.ModelPropertiesProvider propertiesProvider = + getModelPropertiesProvider(); + + // affect it to the model reader + getModelReader().setModelPropertiesProvider(propertiesProvider); + + // set the verbose level of the model reader + getModelReader().setVerbose(verbose); + } + + @Override + public void generate(ChainedFileWriterConfiguration configuration, + File outputDir, + Map<File, List<File>> filesByRoot, + Map<File, List<File>> resourcesByFile) throws IOException { + + Set<File> modelFiles = new HashSet<File>(); + for (List<File> files : filesByRoot.values()) { + modelFiles.addAll(files); + } + File[] filesToRead = modelFiles.toArray(new File[modelFiles.size()]); + + if (configuration.isVerbose()) { + getLog().info("Will read " + filesToRead.length + " model(s)."); + } + + // read memory model from all files models + + model = getModelReader().read(filesToRead); + + // get the last modified source timestamp from reader + lastModifiedSource = getModelReader().getLastModifiedSource(); + + outputDirectory = outputDir; + + } + +} Added: trunk/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/writer/YamlModelChainedFileWriter.java =================================================================== --- trunk/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/writer/YamlModelChainedFileWriter.java (rev 0) +++ trunk/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/writer/YamlModelChainedFileWriter.java 2013-05-04 11:25:19 UTC (rev 1242) @@ -0,0 +1,223 @@ +package org.nuiton.eugene.plugin.writer; + +/* + * #%L + * EUGene :: Maven plugin + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2006 - 2013 CodeLutin + * %% + * 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 + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.nuiton.eugene.ModelPropertiesUtil; +import org.nuiton.eugene.ModelReader; +import org.nuiton.eugene.models.Model; +import org.nuiton.eugene.writer.ChainedFileWriterConfiguration; +import org.nuiton.eugene.writer.ChainedFileWriterToMemoryModel; + +import java.io.File; +import java.io.IOException; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * To create a memory model from yaml model files. + * + * @author tchemit + * @plexus.component role="org.nuiton.eugene.writer.ChainedFileWriter" role-hint="yamlModel2Memory" + * @since 2.6.3 + */ +public class YamlModelChainedFileWriter extends BaseChainedFileWriter implements ChainedFileWriterToMemoryModel { + + public static final String PROP_YAML_MODEL_READER = "yamlModelReader"; + + public static final String PROP_MODEL_PROPERTIES_PROVIDER = "modelPropertiesProvider"; + + public static final String PROP_READER = "reader"; + + protected Model model; + + protected long lastModifiedSource; + + protected File outputDirectory; + + public YamlModelChainedFileWriter() { + super( + PROP_READER, "reader", + PROP_YAML_MODEL_READER, "yamlModelReader", + PROP_MODEL_PROPERTIES_PROVIDER, "modelPropertiesProvider" + ); + } + + @Override + public Model getModel() { + return model; + } + + @Override + public long getLastModifiedSource() { + return lastModifiedSource; + } + + @Override + public File getOutputDirectory() { + return outputDirectory; + } + + @Override + public String getInputProtocol() { + return "yamlmodel"; + } + + @Override + public String getOutputProtocol(String modelType) { + // nothing after java files + //TODO check in engine that a memory chained file has null output protocol + return null; + } + + @Override + public boolean acceptModel(String modelType) { + // accept all models + return acceptObjectModelOrStateModel(modelType); + } + + @Override + public boolean acceptInclude(String include) { + return include.startsWith("yaml:") || + include.endsWith(".yamlobjectmodel") || + include.endsWith(".yamlstatemodel"); + } + + @Override + public String getDefaultIncludes() { + return "**/*.yaml*model"; + } + + @Override + public String getDefaultInputDirectory() { + return "src/main/models"; + } + + @Override + public String getDefaultOutputDirectory() { + return "java"; + } + + @Override + public String getDefaultTestInputDirectory() { + return "src/test/models"; + } + + @Override + public String getDefaultTestOutputDirectory() { + return "test-java"; + } + + protected ModelReader<?> getModelReader() { + return getProperty(PROP_YAML_MODEL_READER, ModelReader.class); + } + + protected String getReader() { + return getProperty(PROP_READER, String.class); + } + + protected ModelPropertiesUtil.ModelPropertiesProvider getModelPropertiesProvider() { + return getProperty(PROP_MODEL_PROPERTIES_PROVIDER, ModelPropertiesUtil.ModelPropertiesProvider.class); + } + + @Override + protected void initWriter(ChainedFileWriterConfiguration configuration) { + super.initWriter(configuration); + + // obtain a reader + ClassLoader classLoader = configuration.getClassLoader(); + ClassLoader loader = classLoader; + if (getModelReader() == null) { + + if (getReader() != null) { + // use a specific reader + String reader = getReader(); + try { + ClassLoader fixedClassLoader = loader; + ModelReader<?> modelReader = (ModelReader<?>) + Class.forName(reader, true, + fixedClassLoader).newInstance(); + //TODO : should check that the reader is compatible with + //TODO : given modelType + properties.put(PROP_YAML_MODEL_READER, modelReader); + } catch (Exception eee) { + throw new IllegalStateException("could not obtain reader " + + reader, eee); + } + } else { + String modelType = configuration.getModelType(); + ModelReader<?> modelReader = + configuration.getModelReaders().get(modelType); + if (modelReader == null) { + throw new IllegalStateException( + "could not find a model reader for modelType : " + + modelType + ", availables readers : " + + configuration.getModelReaders().values()); + } + properties.put(PROP_YAML_MODEL_READER, modelReader); + } + } + + boolean verbose = configuration.isVerbose(); + + // gets the provider of safe tag values and stereotypes + ModelPropertiesUtil.ModelPropertiesProvider propertiesProvider = + getModelPropertiesProvider(); + + // affect it to the model reader + getModelReader().setModelPropertiesProvider(propertiesProvider); + + // set the verbose level of the model reader + getModelReader().setVerbose(verbose); + } + + @Override + public void generate(ChainedFileWriterConfiguration configuration, + File outputDir, + Map<File, List<File>> filesByRoot, + Map<File, List<File>> resourcesByFile) throws IOException { + + Set<File> modelFiles = new HashSet<File>(); + for (List<File> files : filesByRoot.values()) { + modelFiles.addAll(files); + } + File[] filesToRead = modelFiles.toArray(new File[modelFiles.size()]); + + if (configuration.isVerbose()) { + getLog().info("Will read " + filesToRead.length + " model(s)."); + } + + // read memory model from all files models + + model = getModelReader().read(filesToRead); + + // get the last modified source timestamp from reader + lastModifiedSource = getModelReader().getLastModifiedSource(); + + outputDirectory = outputDir; + } + +} Property changes on: trunk/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/writer/YamlModelChainedFileWriter.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native
participants (1)
-
tchemit@users.nuiton.org