branch develop updated (a143849 -> 7304ade)
This is an automated email from the git hooks/post-receive script. New change to branch develop in repository eugene. See https://gitlab.nuiton.org/nuiton/eugene.git discards a143849 Add new property modelExtensionFile on generate mojo + use it to load extension model discards 4bf96ff Introduce de parser factory discards f44d651 Introduce the new mojo to transform old object model extension files to new format discards 0da2ae4 Use LoadModelExtension for legacy model extension files discards 902ad6a Introduce extension package + model extension file parser new a902fda Introduce extension package + model extension file parser (Fixes #4015) new fcc6f96 Use LoadModelExtension for legacy model extension files (Fixes #4015) new 9b821a4 Introduce the new mojo to transform old object model extension files to new format (Fixes #4016) new 70908c5 Introduce de parser factory new 7304ade Add new property modelExtensionFile on generate mojo + use it to load extension model (Fixes #4017) This update added new revisions after undoing existing revisions. That is to say, some revisions that were in the old version of the branch are not in the new version. This situation occurs when a user --force pushes a change and generates a repository containing something like this: * -- * -- B -- O -- O -- O (a143849) \ N -- N -- N refs/heads/develop (7304ade) You should already have received notification emails for all of the O revisions, and so the following emails describe only the N revisions from the common base, B. Any revisions marked "omits" are not gone; other references still refer to them. Any revisions marked "discards" are gone forever. The 5 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "adds" were already present in the repository and have only been added to this reference. Detailed log of new commits: commit 7304ade00186952c44cf2a002ad7b26c20afe142 Author: Tony CHEMIT <chemit@codelutin.com> Date: Sat Sep 10 11:48:36 2016 +0200 Add new property modelExtensionFile on generate mojo + use it to load extension model (Fixes #4017) commit 70908c5c78816a639647afe432b99a3f5d0f4515 Author: Tony CHEMIT <chemit@codelutin.com> Date: Sat Sep 10 11:40:50 2016 +0200 Introduce de parser factory commit 9b821a499f4f19bdf36e5c0acb3488496fe45300 Author: Tony CHEMIT <chemit@codelutin.com> Date: Sat Sep 10 11:40:22 2016 +0200 Introduce the new mojo to transform old object model extension files to new format (Fixes #4016) commit fcc6f961c6c2cc856441d5503000ca1d2a07e908 Author: Tony CHEMIT <chemit@codelutin.com> Date: Sat Sep 10 10:57:44 2016 +0200 Use LoadModelExtension for legacy model extension files (Fixes #4015) commit a902fdaf01542ae54b05fc6fbf04ee6900422e4e Author: Tony CHEMIT <chemit@codelutin.com> Date: Sat Sep 10 10:56:34 2016 +0200 Introduce extension package + model extension file parser (Fixes #4015) Summary of changes: -- To stop receiving notification emails like this one, please contact nuiton.org SCM administrator <admin+scm@nuiton.org>.
This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository eugene. See https://gitlab.nuiton.org/nuiton/eugene.git commit a902fdaf01542ae54b05fc6fbf04ee6900422e4e Author: Tony CHEMIT <chemit@codelutin.com> Date: Sat Sep 10 10:56:34 2016 +0200 Introduce extension package + model extension file parser (Fixes #4015) --- .../extension/CompactModelExtensionFileParser.java | 173 ++++++ .../extension/FlatModelExtensionFileParser.java | 214 ++++++++ .../reader/extension/LoadModelExtension.java | 585 +++++++++++++++++++++ .../reader/extension/ModelExtensionFileParser.java | 16 + .../ModelExtensionFileParserCallback.java | 28 + 5 files changed, 1016 insertions(+) diff --git a/eugene/src/main/java/org/nuiton/eugene/models/object/reader/extension/CompactModelExtensionFileParser.java b/eugene/src/main/java/org/nuiton/eugene/models/object/reader/extension/CompactModelExtensionFileParser.java new file mode 100644 index 0000000..3f18ac4 --- /dev/null +++ b/eugene/src/main/java/org/nuiton/eugene/models/object/reader/extension/CompactModelExtensionFileParser.java @@ -0,0 +1,173 @@ +package org.nuiton.eugene.models.object.reader.extension; + +import com.google.common.base.Preconditions; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.List; + +/** + * Created on 09/09/16. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public class CompactModelExtensionFileParser implements ModelExtensionFileParser { + + /** Logger. */ + private static final Log log = LogFactory.getLog(CompactModelExtensionFileParser.class); + + enum Scope { + MODEL, + PACKAGE, + CLASS + } + + protected Scope scope; + protected String name; + + @Override + public void parse(File file, ModelExtensionFileParserCallback callback) throws IOException { + + scope = null; + name = null; + + List<String> lines = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8); + + for (String line : lines) { + consumeLine(line, callback); + } + + } + + protected void consumeLine(String line, ModelExtensionFileParserCallback callback) { + if (StringUtils.isBlank(line)) { + + // ligne vide + return; + } + if (line.startsWith("#")) { + + // commentaire + return; + } + Scope newScope = getScope(line); + if (newScope != null) { + + // changement de scope + this.scope = newScope; + this.name = null; + return; + } + + Preconditions.checkState(scope != null); + + switch (scope) { + + case MODEL: { + + // la ligne est une tag value ou un stereotype + int index = line.indexOf(' '); + if (index == -1) { + + // stereotype de package + callback.onModelStereotypeFound(line); + + } else { + + // tag value de package + callback.onModelTagValueFound(line.substring(0, index), line.substring(index + 1)); + } + } + break; + case PACKAGE: { + if (line.startsWith(" ")) { + + Preconditions.checkState(name != null, "Pas de nom de paquetage déclaré"); + + line = line.trim(); + + // la ligne est une tag value ou un stereotype + int index = line.indexOf(' '); + if (index == -1) { + + // stereotype de package + callback.onPackageStereotypeFound(name, line); + } else { + + // tag value de package + callback.onPackageTagValueFound(name, line.substring(0, index), line.substring(index + 1)); + } + + break; + + } + + name = line; + + } + break; + case CLASS: + + if (line.startsWith(" ")) { + + Preconditions.checkState(name != null, "Pas de nom de classe déclaré"); + + line = line.trim(); + + // la ligne est une tag value ou un stereotype + int index = line.indexOf(' '); + if (index == -1) { + + int attributeIndex = line.indexOf('.'); + if (attributeIndex == -1) { + + // stereotype de classe + callback.onClassStereotypeFound(name, line); + } else { + + // stereotype d'attribut + callback.onAttributeStereotypeFound(name, line.substring(0, attributeIndex), line.substring(attributeIndex + 1)); + } + + } else { + + String attributeOrTagValue = line.substring(0, index); + + int attributeIndex = attributeOrTagValue.indexOf('.'); + if (attributeIndex == -1) { + + // tag value de classe + callback.onClassTagValueFound(name, attributeOrTagValue, line.substring(index + 1)); + + + } else { + // tag value d'attribut + callback.onAttributeTagValueFound(name, attributeOrTagValue.substring(0, attributeIndex), attributeOrTagValue.substring(attributeIndex + 1), line.substring(index + 1)); + } + + } + + break; + } + + name = line; + + break; + } + } + + protected Scope getScope(String line) { + for (Scope scope : Scope.values()) { + String scopeStr = "[" + scope.name().toLowerCase() + "]"; + if (line.equals(scopeStr)) { + return scope; + } + } + return null; + } +} diff --git a/eugene/src/main/java/org/nuiton/eugene/models/object/reader/extension/FlatModelExtensionFileParser.java b/eugene/src/main/java/org/nuiton/eugene/models/object/reader/extension/FlatModelExtensionFileParser.java new file mode 100644 index 0000000..0f19652 --- /dev/null +++ b/eugene/src/main/java/org/nuiton/eugene/models/object/reader/extension/FlatModelExtensionFileParser.java @@ -0,0 +1,214 @@ +package org.nuiton.eugene.models.object.reader.extension; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.eugene.models.object.reader.InvalidModelPropertiesException; +import org.nuiton.eugene.models.stereotype.InvalidStereotypeSyntaxException; +import org.nuiton.eugene.models.stereotype.Stereotypes; +import org.nuiton.eugene.models.tagvalue.InvalidTagValueSyntaxException; +import org.nuiton.eugene.models.tagvalue.TagValues; +import org.nuiton.util.RecursiveProperties; +import org.nuiton.util.StringUtil; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Properties; +import java.util.Set; +import java.util.regex.Matcher; + +import static org.nuiton.eugene.models.object.reader.AbstractObjectModelReader.ATTRIBUTE; +import static org.nuiton.eugene.models.object.reader.AbstractObjectModelReader.CLASS; +import static org.nuiton.eugene.models.object.reader.AbstractObjectModelReader.MODEL; +import static org.nuiton.eugene.models.object.reader.AbstractObjectModelReader.PACKAGE; +import static org.nuiton.eugene.models.object.reader.AbstractObjectModelReader.STEREOTYPE; +import static org.nuiton.eugene.models.object.reader.AbstractObjectModelReader.TAGVALUE; +import static org.nuiton.eugene.models.object.reader.AbstractObjectModelReader.TAG_VALUE; + +/** + * Created on 09/09/16. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public class FlatModelExtensionFileParser implements ModelExtensionFileParser { + + /** Logger. */ + private static final Log log = LogFactory.getLog(FlatModelExtensionFileParser.class); + + @Override + public void parse(File file, ModelExtensionFileParserCallback callback) throws IOException, InvalidStereotypeSyntaxException, InvalidTagValueSyntaxException { + + Properties prop = new RecursiveProperties(); + + try (Reader inStream = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)) { + prop.load(inStream); + } + + // get all the tagvalues keys and sort them + List<String> keys = new ArrayList<>(); + CollectionUtils.addAll(keys, prop.keys()); + Collections.sort(keys); + + boolean safe = true; + for (String key : keys) { + String value = prop.getProperty(key); + safe &= consumeKeyValue(key, value, callback); + + } + + if (!safe) { + + String errorMessage = "There is some tag value(s) or stereotype(s) failed to be imported from " + file; + throw new InvalidModelPropertiesException(errorMessage); + + } + + } + + protected boolean consumeKeyValue(String key, String value, ModelExtensionFileParserCallback callback) throws InvalidStereotypeSyntaxException, InvalidTagValueSyntaxException { + + boolean safe = true; + + boolean stereoTypeKey = isStereotype(key); + boolean tagValueTypeKey = isTagValue(key); + + if (log.isDebugEnabled()) { + log.debug("Property: '" + key + "' = " + value); + } + + if (key.startsWith(MODEL)) { + + // model stereotype + if (stereoTypeKey) { + + Set<String> stereotypes = Stereotypes.getStereotypes(value); + for (String stereotype : stereotypes) { + safe &= callback.onModelStereotypeFound(stereotype); + } + return safe; + + } + + // model tag value + if (tagValueTypeKey) { + + Matcher matcher = TagValues.getModelMatcher(key); + + String tag = matcher.group(2); + + return callback.onModelTagValueFound(tag, value); + + } + + throw new InvalidModelPropertiesException(key + " is not a valid model entry."); + + } + + if (key.startsWith(PACKAGE)) { + + // package stereotype or tag value + + if (stereoTypeKey) { + + // package stereotype + Matcher matcher = Stereotypes.getPackageMatcher(key); + + String fqn = matcher.group(1); + fqn = StringUtil.substring(fqn, 0, -1); // remove ended . + + Set<String> stereotypes = Stereotypes.getStereotypes(value); + for (String stereotype : stereotypes) { + safe &= callback.onPackageStereotypeFound(fqn, stereotype); + } + return safe; + + } + + if (tagValueTypeKey) { + + // package tag value + + Matcher matcher = TagValues.getPackageMatcher(key); + + String packageName = matcher.group(1); + packageName = StringUtil.substring(packageName, 0, -1); // remove ended . + String tag = matcher.group(3); + + return callback.onPackageTagValueFound(packageName, tag, value); + + } + + throw new InvalidModelPropertiesException(key + " is not a valid package entry."); + + } + + // element tag value or stereotype + + if (stereoTypeKey) { + + // stereotype property + + // check key is ok + Matcher matcher = Stereotypes.getMatcher(key); + + 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); + + Set<String> stereotypes = Stereotypes.getStereotypes(value); + for (String stereotype : stereotypes) { + + if (CLASS.equals(target)) { + safe &= callback.onClassStereotypeFound(fqn, stereotype); + } else if (ATTRIBUTE.equals(target)) { + safe &= callback.onAttributeStereotypeFound(fqn, targetName, stereotype); + } + } + return safe; + + } + if (tagValueTypeKey) { + + // tag value property + + Matcher matcher = TagValues.getMatcher(key); + + String fqn = matcher.group(1); + fqn = StringUtil.substring(fqn, 0, -1); // remove ended dot + // 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); + + if (CLASS.equals(target)) { + return callback.onClassTagValueFound(fqn, tag, value); + } else if (ATTRIBUTE.equals(target)) { + return callback.onAttributeTagValueFound(fqn, targetName, tag, value); + } + } + + throw new InvalidModelPropertiesException(key + " is not a valid class or attribute entry."); + } + + protected boolean isTagValue(String key) { + return key.contains(TAGVALUE) || key.contains(TAG_VALUE); + } + + protected boolean isStereotype(String key) { + return key.contains(STEREOTYPE); + } + +} diff --git a/eugene/src/main/java/org/nuiton/eugene/models/object/reader/extension/LoadModelExtension.java b/eugene/src/main/java/org/nuiton/eugene/models/object/reader/extension/LoadModelExtension.java new file mode 100644 index 0000000..b68e576 --- /dev/null +++ b/eugene/src/main/java/org/nuiton/eugene/models/object/reader/extension/LoadModelExtension.java @@ -0,0 +1,585 @@ +package org.nuiton.eugene.models.object.reader.extension; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.eugene.EugeneTagValues; +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.ObjectModelPackage; +import org.nuiton.eugene.models.object.xml.ObjectModelAssociationClassImpl; +import org.nuiton.eugene.models.object.xml.ObjectModelClassifierImpl; +import org.nuiton.eugene.models.object.xml.ObjectModelImpl; +import org.nuiton.eugene.models.stereotype.InvalidStereotypeSyntaxException; +import org.nuiton.eugene.models.stereotype.MismatchStereotypeTargetException; +import org.nuiton.eugene.models.stereotype.StereotypeDefinitionProvider; +import org.nuiton.eugene.models.stereotype.StereotypeDefinitionProviders; +import org.nuiton.eugene.models.stereotype.StereotypeNotFoundException; +import org.nuiton.eugene.models.tagvalue.InvalidTagValueSyntaxException; +import org.nuiton.eugene.models.tagvalue.MismatchTagValueTargetException; +import org.nuiton.eugene.models.tagvalue.TagValueDefinitionProvider; +import org.nuiton.eugene.models.tagvalue.TagValueDefinitionProviders; +import org.nuiton.eugene.models.tagvalue.TagValueNotFoundException; + +import java.io.File; +import java.io.IOException; + + +/** + * Created on 09/09/16. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public class LoadModelExtension<M extends ObjectModel> implements ModelExtensionFileParserCallback<M> { + + /** Logger. */ + private static final Log log = LogFactory.getLog(LoadModelExtension.class); + + protected final boolean verbose; + protected final boolean strictLoading; + protected final M model; + protected final TagValueDefinitionProvider tagValueDefinitionProvider; + protected final StereotypeDefinitionProvider stereotypeDefinitionProvider; + + public static <M extends ObjectModel> void loadForFlatModel(boolean verbose, boolean strictLoading, M model, File modelExtension) throws IOException { + FlatModelExtensionFileParser parser = new FlatModelExtensionFileParser(); + try { + new LoadModelExtension<>(verbose, strictLoading, model).load(modelExtension); + } catch (InvalidTagValueSyntaxException | InvalidStereotypeSyntaxException e) { + // FIXME + throw new IllegalStateException(e); + } + + } + + public static <M extends ObjectModel> void loadForCompactModel(boolean verbose, boolean strictLoading, M model, File modelExtension) throws IOException { + CompactModelExtensionFileParser parser = new CompactModelExtensionFileParser(); + try { + new LoadModelExtension<>(verbose, strictLoading, model).load(modelExtension); + } catch (InvalidTagValueSyntaxException | InvalidStereotypeSyntaxException e) { + // FIXME + throw new IllegalStateException(e); + } + + } + + public LoadModelExtension(boolean verbose, boolean strictLoading, M model) { + this.verbose = verbose; + this.strictLoading = strictLoading; + this.model = model; + this.tagValueDefinitionProvider = TagValueDefinitionProviders.newProvider(getClass().getClassLoader(), false); + this.stereotypeDefinitionProvider = StereotypeDefinitionProviders.newProvider(getClass().getClassLoader(), false); + } + + public void load(File modelExtension) throws IOException, InvalidTagValueSyntaxException, InvalidStereotypeSyntaxException { + + ModelExtensionFileParser parser; + if (modelExtension.getName().endsWith(".properties")) { + parser = new FlatModelExtensionFileParser(); + } else { + parser = new CompactModelExtensionFileParser(); + } + parser.parse(modelExtension, this); + + } + + @Override + public boolean onModelTagValueFound(String tag, String value) { + + boolean safe = false; + + try { + tagValueDefinitionProvider.validate(tag, ObjectModel.class); + safe = true; + } catch (TagValueNotFoundException e) { + String message = "Invalid model tag value: the tagvalue '" + tag + "' is unknown."; + if (strictLoading) { + log.error(message); + } else { + log.warn(message); + } + } catch (MismatchTagValueTargetException e) { + String message = "Invalid model tag value: this tagvalue '" + tag + "' can not be apply on the model."; + if (strictLoading) { + log.error(message); + } else { + log.warn(message); + } + } + + if (safe) { + + // test if tagValue is deprecated + boolean deprecated = tagValueDefinitionProvider.isDeprecated(tag); + if (deprecated) { + if (log.isWarnEnabled()) { + log.warn("Deprecated tagValue usage: " + value); + } + } + } else { + if (strictLoading) { + // 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 (verbose) { + log.info("model tag value imported " + tag + " → " + value); + } + modelImpl.addTagValue(tag, value); + + return safe; + + } + + @Override + public boolean onModelStereotypeFound(String stereotype) { + + boolean safe = false; + + try { + stereotypeDefinitionProvider.validate(stereotype, ObjectModel.class); + safe = true; + } catch (StereotypeNotFoundException e) { + + String message = "Invalid model stereotype [" + stereotype + "] : the stereotype '" + stereotype + "' is unknown."; + if (strictLoading) { + log.error(message); + } else { + log.warn(message); + } + } catch (MismatchStereotypeTargetException e) { + String message = "Invalid model stereotype [" + stereotype + "] : this stereotype '" + stereotype + "' can not be apply on model."; + if (strictLoading) { + log.error(message); + } else { + log.warn(message); + } + } + + if (safe) { + + // test if stereotype is deprecated + boolean deprecated = stereotypeDefinitionProvider.isDeprecated(stereotype); + if (deprecated) { + log.warn("Deprecated model stereotype usage: " + stereotype); + } + } else { + if (strictLoading) { + // in strict loading do not accept unsafe stereotypes + return false; + } + } + + if (verbose) { + log.info("stereotype imported " + stereotype + " → model."); + } + return safe; + } + + @Override + public boolean onPackageTagValueFound(String packageName, String tag, String value) { + + boolean safe = false; + + try { + tagValueDefinitionProvider.validate(tag, ObjectModelPackage.class); + safe = true; + } catch (TagValueNotFoundException e) { + String message = "Invalid tag value on package [" + packageName + "]: the tagvalue '" + tag + "' is unknown."; + if (strictLoading) { + log.error(message); + } else { + log.warn(message); + } + } catch (MismatchTagValueTargetException e) { + String message = "Invalid tag value on package [" + packageName + "]: this tagvalue '" + tag + "' can not be apply on the model."; + if (strictLoading) { + log.error(message); + } else { + log.warn(message); + } + + } + + if (safe) { + + // test if tagValue is deprecated + boolean deprecated = tagValueDefinitionProvider.isDeprecated(tag); + if (deprecated) { + if (log.isWarnEnabled()) { + log.warn("Deprecated tagValue usage on package [" + packageName + "]: " + value); + } + } + } else { + if (strictLoading) { + // in strict loading do not accept unsafe tags + return false; + } + } + + ObjectModelPackage aPackage = model.getPackage(packageName); + if (verbose) { + log.info("imported tag value on package [" + packageName + "] → " + tag + " = " + value); + } + aPackage.addTagValue(tag, value); + return true; + } + + @Override + public boolean onPackageStereotypeFound(String packageName, String stereotype) { + + boolean safe = false; + try { + stereotypeDefinitionProvider.validate(stereotype, ObjectModelPackage.class); + safe = true; + } catch (StereotypeNotFoundException e) { + String message = "Invalid model stereotype on package [" + packageName + "]: the stereotype '" + stereotype + "' is unknown."; + if (strictLoading) { + log.error(message); + } else { + log.warn(message); + } + } catch (MismatchStereotypeTargetException e) { + String message = "Invalid model stereotype on package [" + packageName + "]: this stereotype '" + stereotype + "' can not be apply on package."; + if (strictLoading) { + log.error(message); + } else { + log.warn(message); + } + } + + if (safe) { + + // test if tagValue is deprecated + boolean deprecated = stereotypeDefinitionProvider.isDeprecated(stereotype); + if (deprecated) { + log.warn("Deprecated stereotype usage on package [" + packageName + "]: " + stereotype); + } + } else { + if (strictLoading) { + // in strict loading do not accept unsafe stereotypes + return false; + } + } + + ObjectModelPackage omc = model.getPackage(packageName); + if (omc == null) { + + // package not found + return false; + } + + omc.addStereotype(stereotype); + + if (verbose) { + log.info("imported stereotype on package [" + packageName + "] → " + stereotype); + } + + return true; + } + + @Override + public boolean onClassTagValueFound(String className, String tag, String value) { + + boolean safe = false; + + try { + tagValueDefinitionProvider.validate(tag, ObjectModelClass.class); + safe = true; + } catch (TagValueNotFoundException e) { + + String message = "Invalid tag value on class [" + className + "]: this tagvalue '" + tag + "' is unknown."; + if (strictLoading) { + log.error(message); + } else { + log.warn(message); + } + + } catch (MismatchTagValueTargetException e) { + String message = "Invalid tag value on class [" + className + "]: this tagvalue '" + tag + "' can not be apply on class scope."; + if (strictLoading) { + log.error(message); + } else { + log.warn(message); + } + } + + if (safe) { + + // test if tagValue is deprecated + boolean deprecated = tagValueDefinitionProvider.isDeprecated(tag); + if (deprecated) { + if (log.isWarnEnabled()) { + log.warn("Deprecated tagValue usage on class [" + className + "] : " + value); + } + } + } else { + + if (strictLoading) { + // in strict loading do not accept unsafe tags + return false; + } + } + + ObjectModelClassifier omc = getClassifier(className); + if (omc == null) { + + // classifier not found + return false; + } + + omc.addTagValue(tag, value); + + if (verbose) { + log.info("tag value imported on class [" + className + "] → " + tag + " = " + value); + } + return true; + + } + + @Override + public boolean onClassStereotypeFound(String className, String stereotype) { + + boolean safe = false; + try { + stereotypeDefinitionProvider.validate(stereotype, ObjectModelClassifier.class); + safe = true; + } catch (StereotypeNotFoundException e) { + + String message = "Invalid model stereotype on class [" + className + "]: the stereotype '" + stereotype + "' is unknown."; + if (strictLoading) { + log.error(message); + } else { + log.warn(message); + } + } catch (MismatchStereotypeTargetException e) { + String message = "Invalid model stereotype on class [" + className + "]: this stereotype '" + stereotype + "' can not be apply on class scope."; + if (strictLoading) { + log.error(message); + } else { + log.warn(message); + } + } + + if (safe) { + + // test if stereotype is deprecated + boolean deprecated = stereotypeDefinitionProvider.isDeprecated(stereotype); + if (deprecated) { + if (log.isWarnEnabled()) { + log.warn("Deprecated stereotype usage on class [" + className + "]: " + stereotype); + } + } + } else { + if (strictLoading) { + // in strict loading do not accept unsafe stereotypes + return false; + } + } + + ObjectModelClassifier omc = getClassifier(className); + if (omc == null) { + + // classifier not found + return false; + } + + if (verbose) { + log.info("stereotype imported on class [" + className + "] → " + stereotype); + } + + return true; + + } + + @Override + public boolean onAttributeTagValueFound(String className, String attributeName, String tag, String value) { + + boolean safe = false; + + try { + tagValueDefinitionProvider.validate(tag, ObjectModelAttribute.class); + safe = true; + } catch (TagValueNotFoundException e) { + + String message = "Invalid tag value on attribute [" + className + "#" + attributeName + "]: this tagvalue '" + tag + "' is unknown."; + if (strictLoading) { + log.error(message); + } else { + log.warn(message); + } + + } catch (MismatchTagValueTargetException e) { + String message = "Invalid tag value on attribute [" + className + "#" + attributeName + "]: this tagvalue '" + tag + "' can not be apply on attribute scope."; + if (strictLoading) { + log.error(message); + } else { + log.warn(message); + } + } + + if (safe) { + + // test if tagValue is deprecated + boolean deprecated = tagValueDefinitionProvider.isDeprecated(tag); + if (deprecated) { + if (log.isWarnEnabled()) { + log.warn("Deprecated tagValue usage on attribute [" + className + "#" + attributeName + "] : " + value); + } + } + } else { + + if (strictLoading) { + // in strict loading do not accept unsafe tags + return false; + } + } + + ObjectModelClassifier omc = getClassifier(className); + if (omc == null) { + + // classifier not found + return false; + } + + ObjectModelAttribute attribute = getAttribute(omc, attributeName); + + if (attribute == null) { + + // attribute not found + return false; + } + attribute.addTagValue(tag, value); + + if (verbose) { + log.info("tag value imported on attribute [" + className + "#" + attributeName + "] → " + tag + " = " + value); + } + return true; + + } + + @Override + public boolean onAttributeStereotypeFound(String className, String attributeName, String stereotype) { + + boolean safe = false; + try { + stereotypeDefinitionProvider.validate(stereotype, ObjectModelAttribute.class); + safe = true; + } catch (StereotypeNotFoundException e) { + + String message = "Invalid model stereotype on attribute [" + className + "#" + attributeName + "]: the stereotype '" + stereotype + "' is unknown."; + if (strictLoading) { + log.error(message); + } else { + log.warn(message); + } + } catch (MismatchStereotypeTargetException e) { + String message = "Invalid model stereotype on attribute [" + className + "#" + attributeName + "]: this stereotype '" + stereotype + "' can not be apply on attribute scope."; + if (strictLoading) { + log.error(message); + } else { + log.warn(message); + } + } + + if (safe) { + + // test if stereotype is deprecated + boolean deprecated = stereotypeDefinitionProvider.isDeprecated(stereotype); + if (deprecated) { + log.warn("Deprecated stereotype usage on attribute [" + className + "]: " + stereotype); + } + } else { + if (strictLoading) { + // in strict loading do not accept unsafe stereotypes + return false; + } + } + + ObjectModelClassifier omc = getClassifier(className); + if (omc == null) { + + // classifier not found + return false; + } + ObjectModelAttribute attribute = getAttribute(omc, attributeName); + if (attribute == null) { + + // attribute not found + return false; + } + attribute.addStereotype(stereotype); + + if (verbose) { + log.info("stereotype imported on attribute [" + className + "#" + attributeName + "] → " + stereotype); + } + + return true; + + } + + + protected ObjectModelClassifier getClassifier(String fqn) { + ObjectModelClassifier omc = model.getClassifier(fqn); + if (omc == null) { + if (log.isWarnEnabled()) { + log.warn("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; + } + + /** + * 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(ObjectModelClassifier 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; + } +} diff --git a/eugene/src/main/java/org/nuiton/eugene/models/object/reader/extension/ModelExtensionFileParser.java b/eugene/src/main/java/org/nuiton/eugene/models/object/reader/extension/ModelExtensionFileParser.java new file mode 100644 index 0000000..13ddfb6 --- /dev/null +++ b/eugene/src/main/java/org/nuiton/eugene/models/object/reader/extension/ModelExtensionFileParser.java @@ -0,0 +1,16 @@ +package org.nuiton.eugene.models.object.reader.extension; + +import org.nuiton.eugene.models.stereotype.InvalidStereotypeSyntaxException; +import org.nuiton.eugene.models.tagvalue.InvalidTagValueSyntaxException; + +import java.io.File; +import java.io.IOException; + +/** + * Created on 09/09/16. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public interface ModelExtensionFileParser { + void parse(File file, ModelExtensionFileParserCallback callback) throws IOException, InvalidStereotypeSyntaxException, InvalidTagValueSyntaxException; +} diff --git a/eugene/src/main/java/org/nuiton/eugene/models/object/reader/extension/ModelExtensionFileParserCallback.java b/eugene/src/main/java/org/nuiton/eugene/models/object/reader/extension/ModelExtensionFileParserCallback.java new file mode 100644 index 0000000..66c7bba --- /dev/null +++ b/eugene/src/main/java/org/nuiton/eugene/models/object/reader/extension/ModelExtensionFileParserCallback.java @@ -0,0 +1,28 @@ +package org.nuiton.eugene.models.object.reader.extension; + +import org.nuiton.eugene.models.object.ObjectModel; + +/** + * Created on 09/09/16. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public interface ModelExtensionFileParserCallback<M extends ObjectModel> { + + boolean onModelTagValueFound(String tag, String value); + + boolean onModelStereotypeFound(String stereotype); + + boolean onPackageTagValueFound(String packageName, String tag, String value); + + boolean onPackageStereotypeFound(String packageName, String stereotype); + + boolean onClassTagValueFound(String className, String tag, String value); + + boolean onClassStereotypeFound(String className, String stereotype); + + boolean onAttributeTagValueFound(String className, String attributeName, String tag, String value); + + boolean onAttributeStereotypeFound(String className, String attributeName, String stereotype); + +} -- To stop receiving notification emails like this one, please contact nuiton.org SCM administrator <admin+scm@nuiton.org>.
This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository eugene. See https://gitlab.nuiton.org/nuiton/eugene.git commit fcc6f961c6c2cc856441d5503000ca1d2a07e908 Author: Tony CHEMIT <chemit@codelutin.com> Date: Sat Sep 10 10:57:44 2016 +0200 Use LoadModelExtension for legacy model extension files (Fixes #4015) --- .../object/reader/AbstractObjectModelReader.java | 32 +++++++++++++++++----- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/eugene/src/main/java/org/nuiton/eugene/models/object/reader/AbstractObjectModelReader.java b/eugene/src/main/java/org/nuiton/eugene/models/object/reader/AbstractObjectModelReader.java index f6fcfa7..53b122b 100644 --- a/eugene/src/main/java/org/nuiton/eugene/models/object/reader/AbstractObjectModelReader.java +++ b/eugene/src/main/java/org/nuiton/eugene/models/object/reader/AbstractObjectModelReader.java @@ -37,6 +37,7 @@ 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.ObjectModelPackage; +import org.nuiton.eugene.models.object.reader.extension.LoadModelExtension; import org.nuiton.eugene.models.object.xml.ObjectModelAssociationClassImpl; import org.nuiton.eugene.models.object.xml.ObjectModelClassifierImpl; import org.nuiton.eugene.models.object.xml.ObjectModelImpl; @@ -124,6 +125,8 @@ public abstract class AbstractObjectModelReader extends ModelReader<ObjectModel> ObjectModel model = new ObjectModelImpl(); + LoadModelExtension<ObjectModel> loadModelExtension = new LoadModelExtension<>(isVerbose(), strictLoading, model); + for (File file : files) { readFileToModel(file, model); @@ -137,15 +140,18 @@ public abstract class AbstractObjectModelReader extends ModelReader<ObjectModel> File propFile = new File(dir, name + ".properties"); if (!propFile.exists()) { if (isVerbose()) { - log.info("Pas de fichier de propriete " + propFile - + " associé au model"); + 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"); + log.info("Lecture du fichier de propriete " + propFile + " associé au model"); + } + try { + loadModelExtension.load(propFile); + } catch (InvalidTagValueSyntaxException | InvalidStereotypeSyntaxException e) { + // FIXME + throw new IllegalStateException(e); } - loadModelProperties(propFile, model); } } @@ -168,6 +174,7 @@ public abstract class AbstractObjectModelReader extends ModelReader<ObjectModel> * @param name attribute name to find * @return the attribute found or null */ + @Deprecated protected ObjectModelAttribute getAttribute(ObjectModelClass clazz, String name) { ObjectModelAttribute result = clazz.getAttribute(name); @@ -191,6 +198,7 @@ public abstract class AbstractObjectModelReader extends ModelReader<ObjectModel> return result; } + @Deprecated public Properties loadModelProperties(File propFile, ObjectModel model) throws IOException { @@ -445,6 +453,7 @@ public abstract class AbstractObjectModelReader extends ModelReader<ObjectModel> } } + @Deprecated protected boolean loadModelTagValue(ObjectModel model, String key, String value) throws InvalidModelPropertiesException { Matcher matcher; @@ -524,6 +533,7 @@ public abstract class AbstractObjectModelReader extends ModelReader<ObjectModel> return true; } + @Deprecated protected boolean loadPackageTagValue(ObjectModel model, String key, String value) throws InvalidModelPropertiesException { Matcher matcher; @@ -600,6 +610,7 @@ public abstract class AbstractObjectModelReader extends ModelReader<ObjectModel> return true; } + @Deprecated protected boolean loadTagValue(ObjectModel model, String key, String value) { Matcher matcher; try { @@ -720,6 +731,7 @@ public abstract class AbstractObjectModelReader extends ModelReader<ObjectModel> return true; } + @Deprecated protected boolean loadModelStereotype(ObjectModel model, String stereotype) throws InvalidModelPropertiesException { @@ -778,6 +790,7 @@ public abstract class AbstractObjectModelReader extends ModelReader<ObjectModel> return true; } + @Deprecated protected boolean loadStereotype(ObjectModel model, String key, String fqn, @@ -864,6 +877,7 @@ public abstract class AbstractObjectModelReader extends ModelReader<ObjectModel> return true; } + @Deprecated protected boolean loadPackageStereotype(ObjectModel model, String key, String fqn, @@ -937,8 +951,8 @@ public abstract class AbstractObjectModelReader extends ModelReader<ObjectModel> return true; } + @Deprecated protected Class<?> getTargetType(String target) { - Class<?> result = null; if (ATTRIBUTE.equals(target)) { return ObjectModelAttribute.class; } @@ -952,9 +966,10 @@ public abstract class AbstractObjectModelReader extends ModelReader<ObjectModel> return ObjectModelPackage.class; } - return result; + return null; } + @Deprecated protected ObjectModelClassifier getClassifier(ObjectModel model, String type, String key, String fqn) { ObjectModelClassifier omc = model.getClassifier(fqn); if (omc == null) { @@ -979,6 +994,7 @@ public abstract class AbstractObjectModelReader extends ModelReader<ObjectModel> return omc; } + @Deprecated protected List<ObjectModelElement> getObjectElements(ObjectModelClassifier omc, String type, String key, String fqn, String target, String targetName) { List<ObjectModelElement> elems = new ArrayList<>(); if (CLASS.equals(target)) { @@ -1016,10 +1032,12 @@ public abstract class AbstractObjectModelReader extends ModelReader<ObjectModel> return elems; } + @Deprecated protected boolean isTagValue(String key) { return key.contains(TAGVALUE) || key.contains(TAG_VALUE); } + @Deprecated protected boolean isStereotype(String key) { return key.contains(STEREOTYPE); } -- To stop receiving notification emails like this one, please contact nuiton.org SCM administrator <admin+scm@nuiton.org>.
This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository eugene. See https://gitlab.nuiton.org/nuiton/eugene.git commit 9b821a499f4f19bdf36e5c0acb3488496fe45300 Author: Tony CHEMIT <chemit@codelutin.com> Date: Sat Sep 10 11:40:22 2016 +0200 Introduce the new mojo to transform old object model extension files to new format (Fixes #4016) --- .../TransformFlatPropertiesToCompactMojo.java | 438 +++++++++++++++++++++ 1 file changed, 438 insertions(+) diff --git a/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/TransformFlatPropertiesToCompactMojo.java b/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/TransformFlatPropertiesToCompactMojo.java new file mode 100644 index 0000000..e5ea74f --- /dev/null +++ b/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/TransformFlatPropertiesToCompactMojo.java @@ -0,0 +1,438 @@ +package org.nuiton.eugene.plugin; + +import com.google.common.io.Files; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.SystemUtils; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.plugins.annotations.ResolutionScope; +import org.apache.maven.project.MavenProject; +import org.nuiton.eugene.models.object.reader.extension.ModelExtensionFileParser; +import org.nuiton.eugene.models.object.reader.extension.ModelExtensionFileParserCallback; +import org.nuiton.eugene.models.object.reader.extension.ModelExtensionFileParserFactory; +import org.nuiton.eugene.models.stereotype.InvalidStereotypeSyntaxException; +import org.nuiton.eugene.models.stereotype.StereotypeAble; +import org.nuiton.eugene.models.tagvalue.InvalidTagValueSyntaxException; +import org.nuiton.eugene.models.tagvalue.TagValueAble; +import org.nuiton.plugin.AbstractPlugin; + +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.Writer; +import java.nio.charset.StandardCharsets; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; + +/** + * Created on 09/09/16. + * + * @author Tony Chemit - chemit@codelutin.com + */ +@Mojo(name = "transform-flat-properties-to-compact", requiresDependencyResolution = ResolutionScope.COMPILE) +public class TransformFlatPropertiesToCompactMojo extends AbstractPlugin { + + /** + * Pour activer le mode verbeux. + * + * @since 2.0.0 + */ + @Parameter(property = "eugene.verbose", defaultValue = "${maven.verbose}") + protected boolean verbose; + + /** + * Encoding to be used for generation of files. + * + * <b>Note:</b> If nothing is filled here, we will use the system + * property {@code file.encoding}. + * + * @since 2.0.0 + */ + @Parameter(property = "eugene.encoding", defaultValue = "${project.build.sourceEncoding}") + protected String encoding; + + /** + * Ne génère rien, analyse juste la configuration. + * + * @since 2.0.0 + */ + @Parameter(property = "eugene.dryRun", defaultValue = "false") + protected boolean dryRun; + + /** + * Maven project. + * + * @since 2.0.0 + */ + @Parameter(defaultValue = "${project}", readonly = true) + protected MavenProject project; + + /** + * The type of model to be used. + * + * By default, use an {@code objectmodel}. + * + * @required + */ + @Parameter(property = "eugene.modelType", defaultValue = "xmlobjectmodel", required = true) + protected String modelType; + + /** + * Where to find model properties files. + */ + @Parameter(property = "eugene.inputDirectory", defaultValue = "${project.basedir}/src/main/xmi", required = true) + protected File inputDirectory; + + /** + * Where to generate yaml file. + */ + @Parameter(property = "eugene.outputDirectory", defaultValue = "${project.basedir}/src/main/xmi", required = true) + protected File outputDirectory; + + @Parameter(property = "eugene.modelName", required = true) + protected String modelName; + + protected File[] inputFiles; + protected File outputFile; + protected String eol; + + @Override + protected void init() throws Exception { + + inputFiles = inputDirectory.listFiles(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return name.endsWith(".properties"); + } + }); + + getLog().info("Found " + inputFiles.length + " model extension properties file(s)."); + + outputFile = new File(outputDirectory, modelName + ".objectmodel-ext"); + + } + + @Override + protected void doAction() throws Exception { + + ModelBeanBuilder modelBeanBuilder = new ModelBeanBuilder(modelName); + + for (File inputFile : inputFiles) { + + modelBeanBuilder.addFile(inputFile); + } + + eol = SystemUtils.LINE_SEPARATOR; + ModelBean modelBean = modelBeanBuilder.build(); + + StringBuilder result = new StringBuilder(); + + result.append("[model]").append(eol); + appendMap(modelBean.tagValues, "", "tagvalues", result); + appendSet(modelBean.stereotypes, "", "stereotypes", result); + + result.append(eol).append("[package]").append(eol); + + if (modelBean.withPackages()) { + + for (PackageBean packageBean : modelBean.packages) { + + result.append(packageBean.name).append(eol); + appendMap(packageBean.tagValues, " ", "tagvalues", result); + appendSet(packageBean.stereotypes, " ", "stereotypes", result); + + } + + } + + result.append(eol).append("[class]").append(eol); + + if (modelBean.withClasses()) { + + for (ClassBean classBean : modelBean.classes) { + + result.append(classBean.name).append(eol); + appendMap(classBean.tagValues, " ", "tagvalues", result); + appendSet(classBean.stereotypes, " ", "stereotypes", result); + appendMap(classBean.getAttributesTagValues(), " ", "attributes.tagvalues", result); + appendSet(classBean.getAttributesStereotypes(), " ", "attributes.stereotypes", result); + + } + + } + + if (dryRun) { + + getLog().info("\n\nDryRun mode\ncontent:\n\n" + result.toString() + "\n\n"); + } else { + + getLog().info("Generate to: " + outputFile); + Writer writer = Files.newWriter(outputFile, StandardCharsets.UTF_8); + try { + + IOUtils.write(result.toString(), writer); + writer.close(); + + } finally { + IOUtils.closeQuietly(writer); + } + + } + + } + + protected void appendMap(Map<String, String> map, String prefix, String name, StringBuilder result) { + if (!map.isEmpty()) { + for (Map.Entry<String, String> entry : map.entrySet()) { + result.append(prefix).append(entry.getKey()).append(" ").append(entry.getValue()).append(eol); + } + } + } + + protected void appendSet(Set<String> set, String prefix, String name, StringBuilder result) { + if (!set.isEmpty()) { + for (String stereotype : set) { + result.append(prefix).append(stereotype).append(eol); + } + } + } + + @Override + public MavenProject getProject() { + return project; + } + + @Override + public void setProject(MavenProject project) { + this.project = project; + } + + @Override + public boolean isVerbose() { + return verbose; + } + + @Override + public void setVerbose(boolean verbose) { + this.verbose = verbose; + } + + public static class ModelBean extends ElementBean { + + Set<PackageBean> packages = new TreeSet<>(); + Set<ClassBean> classes = new TreeSet<>(); + + public ModelBean(String name) { + super(name); + } + + @Override + public boolean isEmpty() { + return super.isEmpty() && classes.isEmpty() && packages.isEmpty(); + } + + public PackageBean getOrCreatePackage(final String packageName) { + + PackageBean result = null; + for (PackageBean packageBean : packages) { + if (packageName.equals(packageBean.name)) { + result = packageBean; + break; + } + } + if (result == null) { + result = new PackageBean(packageName); + packages.add(result); + } + return result; + } + + public ClassBean getOrCreateClass(final String className) { + + ClassBean result = null; + for (ClassBean packageBean : classes) { + if (className.equals(packageBean.name)) { + result = packageBean; + break; + } + } + if (result == null) { + result = new ClassBean(className); + classes.add(result); + } + return result; + } + + public AttributeBean getOrCreateClassAttribute(String className, String attributeName) { + ClassBean classBean = getOrCreateClass(className); + return classBean.getOrCreateAttribute(attributeName); + } + + public boolean withClasses() { + return !classes.isEmpty(); + } + + public boolean withPackages() { + return !packages.isEmpty(); + } + } + + public static class PackageBean extends ElementBean { + + public PackageBean(String name) { + super(name); + } + + } + + public static class ClassBean extends ElementBean { + + Set<AttributeBean> attributes = new TreeSet<>(); + + public ClassBean(String name) { + super(name); + } + + @Override + public boolean isEmpty() { + return super.isEmpty() && attributes.isEmpty(); + } + + public Map<String, String> getAttributesTagValues() { + Map<String, String> attributesTagValues = new TreeMap<>(); + for (AttributeBean attributeBean : attributes) { + + for (Map.Entry<String, String> entry : attributeBean.tagValues.entrySet()) { + attributesTagValues.put(attributeBean.name + "." + entry.getKey(), entry.getValue()); + } + } + return attributesTagValues; + } + + public Set<String> getAttributesStereotypes() { + Set<String> attributesStereotypes = new TreeSet<>(); + for (AttributeBean attributeBean : attributes) { + + for (String entry : attributeBean.stereotypes) { + attributesStereotypes.add(attributeBean.name + "." + entry); + } + } + return attributesStereotypes; + } + + public AttributeBean getOrCreateAttribute(String attributeName) { + AttributeBean result = null; + for (AttributeBean attributeBean : attributes) { + if (attributeName.equals(attributeBean.name)) { + result = attributeBean; + break; + } + } + if (result == null) { + result = new AttributeBean(attributeName); + attributes.add(result); + } + return result; + } + } + + public static class AttributeBean extends ElementBean { + + public AttributeBean(String name) { + super(name); + } + } + + public static class ElementBean implements Comparable<ElementBean> { + final String name; + final Map<String, String> tagValues = new TreeMap<>(); + final Set<String> stereotypes = new TreeSet<>(); + + public ElementBean(String name) { + this.name = name; + } + + @Override + public int compareTo(ElementBean o) { + return name.compareTo(o.name); + } + + public <T extends TagValueAble & StereotypeAble> void load(T tag) { + this.tagValues.putAll(tag.getTagValues()); + this.stereotypes.addAll(tag.getStereotypes()); + } + + public boolean isEmpty() { + return tagValues.isEmpty() && stereotypes.isEmpty(); + } + } + + private static class ModelBeanBuilder implements ModelExtensionFileParserCallback { + + private final ModelExtensionFileParser parser; + private final ModelBean modelBean; + + public ModelBeanBuilder(String modelName) { + this.parser = ModelExtensionFileParserFactory.newFlatPaser(); + this.modelBean = new ModelBean(modelName); + } + + public ModelBean build() { + return modelBean; + } + + @Override + public boolean onModelTagValueFound(String tag, String value) { + modelBean.tagValues.put(tag, value); + return true; + } + + @Override + public boolean onModelStereotypeFound(String stereotype) { + modelBean.stereotypes.add(stereotype); + return true; + } + + @Override + public boolean onPackageTagValueFound(String packageName, String tag, String value) { + modelBean.getOrCreatePackage(packageName).tagValues.put(tag, value); + return true; + } + + @Override + public boolean onPackageStereotypeFound(String packageName, String stereotype) { + modelBean.getOrCreatePackage(packageName).stereotypes.add(stereotype); + return true; + } + + @Override + public boolean onClassTagValueFound(String className, String tag, String value) { + modelBean.getOrCreateClass(className).tagValues.put(tag, value); + return true; + } + + @Override + public boolean onClassStereotypeFound(String className, String stereotype) { + modelBean.getOrCreateClass(className).stereotypes.add(stereotype); + return true; + } + + @Override + public boolean onAttributeTagValueFound(String className, String attributeName, String tag, String value) { + modelBean.getOrCreateClassAttribute(className, attributeName).tagValues.put(tag, value); + return true; + } + + @Override + public boolean onAttributeStereotypeFound(String className, String attributeName, String stereotype) { + modelBean.getOrCreateClassAttribute(className, attributeName).stereotypes.add(stereotype); + return true; + } + + public void addFile(File inputFile) throws InvalidTagValueSyntaxException, InvalidStereotypeSyntaxException, IOException { + parser.parse(inputFile, this); + } + } +} -- To stop receiving notification emails like this one, please contact nuiton.org SCM administrator <admin+scm@nuiton.org>.
This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository eugene. See https://gitlab.nuiton.org/nuiton/eugene.git commit 70908c5c78816a639647afe432b99a3f5d0f4515 Author: Tony CHEMIT <chemit@codelutin.com> Date: Sat Sep 10 11:40:50 2016 +0200 Introduce de parser factory --- .../reader/extension/LoadModelExtension.java | 7 +---- .../extension/ModelExtensionFileParserFactory.java | 34 ++++++++++++++++++++++ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/eugene/src/main/java/org/nuiton/eugene/models/object/reader/extension/LoadModelExtension.java b/eugene/src/main/java/org/nuiton/eugene/models/object/reader/extension/LoadModelExtension.java index b68e576..8b9d72b 100644 --- a/eugene/src/main/java/org/nuiton/eugene/models/object/reader/extension/LoadModelExtension.java +++ b/eugene/src/main/java/org/nuiton/eugene/models/object/reader/extension/LoadModelExtension.java @@ -75,12 +75,7 @@ public class LoadModelExtension<M extends ObjectModel> implements ModelExtension public void load(File modelExtension) throws IOException, InvalidTagValueSyntaxException, InvalidStereotypeSyntaxException { - ModelExtensionFileParser parser; - if (modelExtension.getName().endsWith(".properties")) { - parser = new FlatModelExtensionFileParser(); - } else { - parser = new CompactModelExtensionFileParser(); - } + ModelExtensionFileParser parser = ModelExtensionFileParserFactory.newParser(modelExtension); parser.parse(modelExtension, this); } diff --git a/eugene/src/main/java/org/nuiton/eugene/models/object/reader/extension/ModelExtensionFileParserFactory.java b/eugene/src/main/java/org/nuiton/eugene/models/object/reader/extension/ModelExtensionFileParserFactory.java new file mode 100644 index 0000000..88e1091 --- /dev/null +++ b/eugene/src/main/java/org/nuiton/eugene/models/object/reader/extension/ModelExtensionFileParserFactory.java @@ -0,0 +1,34 @@ +package org.nuiton.eugene.models.object.reader.extension; + +import org.apache.commons.lang3.NotImplementedException; + +import java.io.File; + +/** + * Created on 10/09/16. + * + * @author Tony Chemit - chemit@codelutin.com + */ +public class ModelExtensionFileParserFactory { + + public static FlatModelExtensionFileParser newFlatPaser() { + return new FlatModelExtensionFileParser(); + } + + public static CompactModelExtensionFileParser newCompactPaser() { + return new CompactModelExtensionFileParser(); + } + + + public static ModelExtensionFileParser newParser(File file) { + ModelExtensionFileParser parser; + if (file.getName().endsWith(".properties")) { + parser = new FlatModelExtensionFileParser(); + } else if (file.getName().endsWith(".model-ex")) { + parser = new CompactModelExtensionFileParser(); + } else { + throw new NotImplementedException("can't find parser for file: " + file); + } + return parser; + } +} -- To stop receiving notification emails like this one, please contact nuiton.org SCM administrator <admin+scm@nuiton.org>.
This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository eugene. See https://gitlab.nuiton.org/nuiton/eugene.git commit 7304ade00186952c44cf2a002ad7b26c20afe142 Author: Tony CHEMIT <chemit@codelutin.com> Date: Sat Sep 10 11:48:36 2016 +0200 Add new property modelExtensionFile on generate mojo + use it to load extension model (Fixes #4017) --- .../org/nuiton/eugene/plugin/GenerateMojo.java | 13 +++++++++++++ .../writer/BaseChainedFileWriterToMemoryModel.java | 22 +++++++++++++++++++--- .../writer/ChainedFileWriterConfiguration.java | 2 ++ 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/GenerateMojo.java b/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/GenerateMojo.java index e5981de..a76908c 100644 --- a/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/GenerateMojo.java +++ b/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/GenerateMojo.java @@ -295,6 +295,14 @@ public class GenerateMojo extends AbstractPlugin implements ChainedFileWriterCon protected boolean failIfUnsafe; /** + * To use a new object model extension file. + * + * @since 3.0 + */ + @Parameter(property = "eugene.modelExtensionFile") + protected File modelExtensionFile; + + /** * Maven project. * * @since 2.0.0 @@ -745,6 +753,11 @@ public class GenerateMojo extends AbstractPlugin implements ChainedFileWriterCon return getProject().getBasedir(); } + @Override + public File getModelExtensionFile() { + return modelExtensionFile; + } + /** * @return the string representation of excludesTemplates * (separated by comma) diff --git a/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/writer/BaseChainedFileWriterToMemoryModel.java b/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/writer/BaseChainedFileWriterToMemoryModel.java index 47b6a29..b714592 100644 --- a/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/writer/BaseChainedFileWriterToMemoryModel.java +++ b/eugene-maven-plugin/src/main/java/org/nuiton/eugene/plugin/writer/BaseChainedFileWriterToMemoryModel.java @@ -24,7 +24,11 @@ package org.nuiton.eugene.plugin.writer; import org.nuiton.eugene.ModelReader; import org.nuiton.eugene.models.Model; +import org.nuiton.eugene.models.object.ObjectModel; +import org.nuiton.eugene.models.object.reader.extension.LoadModelExtension; +import org.nuiton.eugene.models.stereotype.InvalidStereotypeSyntaxException; import org.nuiton.eugene.models.stereotype.StereotypeDefinitionProvider; +import org.nuiton.eugene.models.tagvalue.InvalidTagValueSyntaxException; import org.nuiton.eugene.models.tagvalue.TagValueDefinitionProvider; import org.nuiton.eugene.writer.ChainedFileWriterConfiguration; import org.nuiton.eugene.writer.ChainedFileWriterToMemoryModel; @@ -155,7 +159,7 @@ public abstract class BaseChainedFileWriterToMemoryModel extends BaseChainedFile throw eee; } catch (Exception eee) { throw new IllegalStateException("could not obtain reader " - + reader, eee); + + reader, eee); } } else { @@ -165,8 +169,8 @@ public abstract class BaseChainedFileWriterToMemoryModel extends BaseChainedFile if (modelReader == null) { throw new IllegalStateException( "could not find a model reader for modelType: " + - modelType + ", and input type: " + inputType + ", availables readers : " + - configuration.getModelHelper().getModelReaders().values() + modelType + ", and input type: " + inputType + ", availables readers : " + + configuration.getModelHelper().getModelReaders().values() ); } @@ -209,6 +213,18 @@ public abstract class BaseChainedFileWriterToMemoryModel extends BaseChainedFile // read memory model from all files models model = getModelReader().read(filesToRead); + if (model instanceof ObjectModel && configuration.getModelExtensionFile() != null) { + + LoadModelExtension<ObjectModel> loadModelExtension = new LoadModelExtension<>(configuration.isVerbose(), isFailIfUnsafe(), (ObjectModel) model); + + try { + loadModelExtension.load(configuration.getModelExtensionFile()); + } catch (InvalidTagValueSyntaxException | InvalidStereotypeSyntaxException e) { + //FIXME + throw new IllegalStateException(e); + } + } + if (configuration.isVerbose()) { getLog().info("Last modified file: " + lastModifiedFile + " - " + new Date(getLastModifiedSource())); diff --git a/eugene/src/main/java/org/nuiton/eugene/writer/ChainedFileWriterConfiguration.java b/eugene/src/main/java/org/nuiton/eugene/writer/ChainedFileWriterConfiguration.java index 614af5d..def562c 100644 --- a/eugene/src/main/java/org/nuiton/eugene/writer/ChainedFileWriterConfiguration.java +++ b/eugene/src/main/java/org/nuiton/eugene/writer/ChainedFileWriterConfiguration.java @@ -85,4 +85,6 @@ public interface ChainedFileWriterConfiguration { /** @return the classloader to use to seek for resources */ ClassLoader getClassLoader(); + File getModelExtensionFile(); + } -- To stop receiving notification emails like this one, please contact nuiton.org SCM administrator <admin+scm@nuiton.org>.
participants (1)
-
nuiton.org scm