org.nuiton.eugene.models.object.xml.ObjectModelImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of eugene Show documentation
Show all versions of eugene Show documentation
Efficient Universal Generator.
/*
* #%L
* EUGene :: EUGene
* %%
* 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
* .
* #L%
*/
package org.nuiton.eugene.models.object.xml;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.eugene.ModelHelper;
import org.nuiton.eugene.models.object.ObjectModel;
import org.nuiton.eugene.models.object.ObjectModelAttribute;
import org.nuiton.eugene.models.object.ObjectModelClass;
import org.nuiton.eugene.models.object.ObjectModelClassifier;
import org.nuiton.eugene.models.object.ObjectModelEnumeration;
import org.nuiton.eugene.models.object.ObjectModelInterface;
import org.nuiton.eugene.models.object.ObjectModelPackage;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Implementation class for the root node abstraction of object model trees.
* This an entry point for browsing a model tree. This object offers as well
* several facilities for a direct access to some of the object model elements.
* In this concrete class, the tree is build by parsing an object model xml
* description using lutinxml XMLObjectParser.
*
* Created: 14 janv. 2004
*
* @author Cédric Pineau - [email protected]
* @plexus.component role="org.nuiton.eugene.models.Model" role-hint="objectmodel"
*/
public class ObjectModelImpl implements ObjectModel {
/** logger */
private static final Log log = LogFactory.getLog(ObjectModelImpl.class);
protected String name;
protected String version;
protected Map classes = new HashMap<>();
protected Map packages = new HashMap<>();
protected Map interfaces = new HashMap<>();
protected Map classifiers = new HashMap<>();
protected Map enumerations = new HashMap<>();
protected List comments = new ArrayList<>();
protected Map tagValues = new HashMap<>();
protected Set stereotypes = new HashSet<>();
/**
* Used to add others specific object to the model
* The key defined must be unique to get the significative extension associated to
*/
private Map extensions = new HashMap<>();
@Override
public String getModelType() {
return ModelHelper.ModelType.OBJECT.getAlias();
}
public void setName(String name) {
this.name = name;
}
public void setVersion(String version) {
this.version = version;
}
@Override
public String getVersion() {
return version;
}
public void addPackage(ObjectModelPackageImpl aPackage) {
aPackage.postInit();
aPackage.setObjectModelImpl(this);
if (!aPackage.isExtern()) {
ObjectModelPackageImpl initialElement = (ObjectModelPackageImpl)
packages.get(aPackage.getName());
if (initialElement == null) {
packages.put(aPackage.getName(), aPackage);
} else {
// La package existe déjà. On va prendre tout ce que contient la
// nouvelle package et l'ajouter à la précédente si nécessaire.
mergePackages(initialElement, aPackage);
}
}
}
public void addClass(ObjectModelClassImpl clazz) {
//if (clazz == null)
// return new ObjectModelClassImpl(this, null);
clazz.postInit();
clazz.setObjectModelImpl(this);
if (!clazz.isExtern()) {
ObjectModelElementImpl initialElement = (ObjectModelElementImpl)
classes.get(clazz.getQualifiedName());
if (initialElement == null) {
classes.put(clazz.getQualifiedName(), clazz);
classifiers.put(clazz.getQualifiedName(), clazz);
} else {
if (!(initialElement instanceof ObjectModelClassImpl)) {
throw new IllegalArgumentException(
"\"" + clazz + "\" is incompatible with already " +
"defined element \"" + initialElement + "\"");
}
ObjectModelClassImpl initialClazz =
(ObjectModelClassImpl) initialElement;
// La classe existe déjà. On va prendre tout ce que contient la
// nouvelle classe et l'ajouter à la précédente si nécessaire.
mergeClasses(initialClazz, clazz);
// clazz = initialClazz;
}
}
//return clazz;
}
public void addAssociationClass(ObjectModelAssociationClassImpl clazz) {
//if (clazz == null)
// return new ObjectModelAssociationClassImpl(this, null);
clazz.postInit();
clazz.setObjectModelImpl(this);
if (!clazz.isExtern()) {
ObjectModelElementImpl initialElement = (ObjectModelElementImpl)
classes.get(clazz.getQualifiedName());
if (initialElement == null) {
classes.put(clazz.getQualifiedName(), clazz);
classifiers.put(clazz.getQualifiedName(), clazz);
} else {
if (!(initialElement instanceof ObjectModelAssociationClassImpl)) {
throw new IllegalArgumentException(
"\"" + clazz + "\" is incompatible with " +
"already defined element \"" + initialElement +
"\""
);
}
ObjectModelAssociationClassImpl initialClazz =
(ObjectModelAssociationClassImpl) initialElement;
mergeAssociationClasses(initialClazz, clazz);
// clazz = initialClazz;
}
}
//return clazz;
}
public void addComment(String comment) {
comments.add(comment);
}
/**
* Returns the name of this model.
*
* @return the name of this model.
*/
@Override
public String getName() {
return name;
}
@Override
public Collection getPackages() {
return packages.values();
}
@Override
public ObjectModelPackage getPackage(String packageName) {
return packages.get(packageName);
}
@Override
public ObjectModelPackage getPackage(ObjectModelClassifier classifier) {
return getPackage(classifier.getPackageName());
}
@Override
public boolean hasPackage(String packageName) {
return packages.containsKey(packageName);
}
/**
* Returns all classifiers defined in this model.
*
* @return a Collection containing all ObjectModelClassifier for this model.
* @see ObjectModelClassifier
*/
@Override
public Collection getClassifiers() {
return classifiers.values();
}
/**
* Returns the classifier corresponding to the given qualified name, or null
* if the model contains no classifier for this qualified name.
*
* @param qualifiedClassifierName -
* the qualified name of the classifier to retrieve.
* @return the ObjectModelClassifier of the found classifier, or null if the
* model contains no classifier for this qualified name.
*/
@Override
public ObjectModelClassifier getClassifier(String qualifiedClassifierName) {
return qualifiedClassifierName == null ? null
: classifiers.get(qualifiedClassifierName);
}
/**
* Returns all classes defined in this model.
*
* @return a Collection containing all ObjectModelClass for this model.
* @see ObjectModelClass
*/
@Override
public Collection getClasses() {
return classes.values();
}
/**
* Returns the class corresponding to the given qualified name, or null if
* the model contains no class for this qualified name.
*
* @param qualifiedClassName -
* the qualified name of the class to retrieve.
* @return the ObjectModelClass of the found class, or null if the model
* contains no class for this qualified name.
*/
@Override
public ObjectModelClass getClass(String qualifiedClassName) {
if (qualifiedClassName == null) {
return null;
}
if (!hasClass(qualifiedClassName)) {
if (log.isDebugEnabled()) {
log.debug("Class " + qualifiedClassName + " not found in model");
}
return null;
}
return classes.get(qualifiedClassName);
}
@Override
public boolean hasClass(String qualifiedClassName) {
boolean hasClass = classes.containsKey(qualifiedClassName);
return hasClass;
}
public void addInterface(ObjectModelInterfaceImpl interfacez) {
//if (interfacez == null)
// return new ObjectModelInterfaceImpl(this, null);
interfacez.postInit();
interfacez.setObjectModelImpl(this);
if (!interfacez.isExtern()) {
ObjectModelElementImpl initialElement = (ObjectModelElementImpl)
interfaces.get(interfacez.getQualifiedName());
if (initialElement == null) {
interfaces.put(interfacez.getQualifiedName(), interfacez);
classifiers.put(interfacez.getQualifiedName(), interfacez);
} else {
if (!(initialElement instanceof ObjectModelInterfaceImpl)) {
throw new IllegalArgumentException(
"\"" + interfacez + "\" is incompatible with " +
"already defined element \"" + initialElement +
"\"");
}
ObjectModelInterfaceImpl initialInterfacez =
(ObjectModelInterfaceImpl) initialElement;
mergeClassifiers(initialInterfacez, interfacez);
// interfacez = initialInterfacez;
}
}
//return interfacez;
}
/**
* Returns the interface corresponding to the given qualified name, or null
* if the model contains no interface for this qualified name.
*
* @param qualifiedInterfaceName -
* the qualified name of the interface to retrieve.
* @return the ObjectModelInterface of the found interface, or null if the
* model contains no interface for this qualified name.
*/
@Override
public ObjectModelInterface getInterface(String qualifiedInterfaceName) {
ObjectModelInterface result = interfaces.get(qualifiedInterfaceName);
if (result == null) {
if (log.isDebugEnabled()) {
log.debug("Interface " + qualifiedInterfaceName +
" not found in model");
}
}
return result;
}
/**
* Returns all interfaces defined in this model.
*
* @return a Collection containing all ObjectModelInterface for this model.
* @see ObjectModelInterface
*/
@Override
public Collection getInterfaces() {
return interfaces.values();
}
public void addEnumeration(ObjectModelEnumerationImpl enumeration) {
enumeration.postInit();
enumeration.setObjectModelImpl(this);
classifiers.put(enumeration.getQualifiedName(), enumeration);
enumerations.put(enumeration.getQualifiedName(), enumeration);
}
@Override
public Collection getEnumerations() {
return enumerations.values();
}
@Override
public ObjectModelEnumeration getEnumeration(String qualifiedEnumerationName) {
ObjectModelEnumeration result =
enumerations.get(qualifiedEnumerationName);
if (result == null) {
if (log.isDebugEnabled()) {
log.debug("Enumeration " + qualifiedEnumerationName +
" not found in model");
}
}
return result;
}
/**
* Returns all comments not lied to a particular model element
*
* @return a List containing all comments for this model as Strings.
*/
@Override
public List getComments() {
return comments;
}
@Override
public Set getStereotypes() {
return stereotypes;
}
@Override
public boolean hasStereotype(String stereotypeName) {
return stereotypes.contains(stereotypeName);
}
@Override
public void addStereotype(String stereotype) {
stereotypes.add(stereotype);
}
protected void mergePackages(
ObjectModelPackageImpl initialPackage,
ObjectModelPackageImpl additionalPackage) {
Iterator it;
String description = "";
String sourceDoc = "";
if (initialPackage.documentation != null) {
description += initialPackage.getDescription();
if (initialPackage.documentation.contains("--")) {
sourceDoc += initialPackage.getSourceDocumentation();
}
}
if (additionalPackage.documentation != null) {
if (!description.equals("")) {
description += " - ";
}
description += additionalPackage.getDescription();
if (additionalPackage.documentation.contains("--")) {
if (!sourceDoc.equals("")) {
sourceDoc += " - ";
}
sourceDoc += additionalPackage.getSourceDocumentation();
}
}
if (!description.equals("") || !sourceDoc.equals("")) {
initialPackage.documentation = description + "--" + sourceDoc;
}
for (it = additionalPackage.getComments().iterator(); it.hasNext(); ) {
String comment = (String) it.next();
if (!initialPackage.comments.contains(comment)) {
initialPackage.comments.add(comment);
}
}
for (it = additionalPackage.getStereotypes().iterator(); it.hasNext(); ) {
String stereotype = (String) it.next();
if (!initialPackage.getStereotypes().contains(stereotype)) {
initialPackage.stereotypes.add(stereotype);
}
}
for (it = additionalPackage.getTagValues().keySet().iterator(); it.hasNext(); ) {
String tagName = (String) it.next();
if (!initialPackage.getTagValues().containsKey(tagName)) {
initialPackage.tagValues.put(
tagName,
additionalPackage.getTagValue(tagName)
);
}
}
}
protected void mergeClassifiers(
ObjectModelClassifierImpl initialClazzifier,
ObjectModelClassifierImpl additionalClazzifier) {
Iterator it;
// On n'utilise pas les parsetXXX puisque les post-init sont censés être
// déjà faits...
// System.out.println("Doc initial : " +
// initialClazzifier.documentation);
// System.out.println("Doc additional : " +
// additionalClazzifier.documentation);
String description = "";
String sourceDoc = "";
if (initialClazzifier.documentation != null) {
description += initialClazzifier.getDescription();
if (initialClazzifier.documentation.contains("--")) {
sourceDoc += initialClazzifier.getSourceDocumentation();
}
}
if (additionalClazzifier.documentation != null) {
if (!description.equals("")) {
description += " - ";
}
description += additionalClazzifier.getDescription();
if (additionalClazzifier.documentation.contains("--")) {
if (!sourceDoc.equals("")) {
sourceDoc += " - ";
}
sourceDoc += additionalClazzifier.getSourceDocumentation();
}
}
if (!description.equals("") || !sourceDoc.equals("")) {
initialClazzifier.documentation = description + "--" + sourceDoc;
}
// System.out.println("Doc after : " + initialClazzifier.documentation);
for (it = additionalClazzifier.interfacesRefs.iterator(); it.hasNext(); ) {
ObjectModelImplRef interfaceRef = (ObjectModelImplRef) it.next();
if (!contains(initialClazzifier.interfacesRefs, interfaceRef)) {
initialClazzifier.interfacesRefs.add(interfaceRef);
}
initialClazzifier.interfaces = null; // On force ainsi à
// regénérer l'objet
}
for (it = additionalClazzifier.getOperations().iterator(); it.hasNext(); ) {
ObjectModelOperationImpl operation = (ObjectModelOperationImpl) it.next();
if (!contains(initialClazzifier.getOperations(), operation)) {
initialClazzifier.operations.add(operation);
}
}
for (it = additionalClazzifier.getDependencies().iterator(); it.hasNext(); ) {
ObjectModelDependencyImpl dependency = (ObjectModelDependencyImpl) it.next();
if (!contains(initialClazzifier.getDependencies(), dependency)) {
initialClazzifier.dependencies.add(dependency);
}
}
for (it = additionalClazzifier.getComments().iterator(); it.hasNext(); ) {
String comment = (String) it.next();
if (!initialClazzifier.comments.contains(comment)) {
initialClazzifier.comments.add(comment);
}
}
for (it = additionalClazzifier.getStereotypes().iterator(); it.hasNext(); ) {
String stereotype = (String) it.next();
if (!initialClazzifier.getStereotypes().contains(stereotype)) {
initialClazzifier.stereotypes.add(stereotype);
}
}
for (it = additionalClazzifier.getTagValues().keySet().iterator(); it.hasNext(); ) {
String tagName = (String) it.next();
if (!initialClazzifier.getTagValues().containsKey(tagName)) {
initialClazzifier.tagValues.put(
tagName,
additionalClazzifier.getTagValue(tagName)
);
}
}
}
/**
* This method takes two ObjectModelClassImpl and merges both of them in the
* first one
*
* @param initialClazz the instance of ObjectModelClassImpl to be modified
* @param additionalClazz the instance of ObjectModelClassImpl tu be used for merging
*/
private void mergeClasses(ObjectModelClassImpl initialClazz,
ObjectModelClassImpl additionalClazz) {
Iterator it;
mergeClassifiers(initialClazz, additionalClazz);
for (it = additionalClazz.getAttributes().iterator(); it.hasNext(); ) {
ObjectModelAttributeImpl attribute =
(ObjectModelAttributeImpl) it.next();
if (!contains(initialClazz.getAttributes(), attribute)) {
initialClazz.attributes.put(attribute.getName(), attribute);
initialClazz.orderedAttributes.add(attribute);
}
}
for (it = additionalClazz.superclassesRefs.iterator(); it.hasNext(); ) {
ObjectModelImplRef superclassRef = (ObjectModelImplRef) it.next();
if (!contains(initialClazz.superclassesRefs, superclassRef)) {
initialClazz.superclassesRefs.add(superclassRef);
}
initialClazz.superclasses = null; // On force ainsi à regénérer
// l'objet
}
}
private void mergeAssociationClasses(
ObjectModelAssociationClassImpl initialAssocClazz,
ObjectModelAssociationClassImpl additionalAssocClazz) {
mergeClasses(initialAssocClazz, additionalAssocClazz);
Iterator it;
for (it = additionalAssocClazz.participantsRefs.iterator(); it.hasNext(); ) {
ObjectModeImplAssociationClassParticipant participant =
(ObjectModeImplAssociationClassParticipant) it.next();
if (!contains(initialAssocClazz.participantsRefs, participant)) {
initialAssocClazz.participantsRefs.add(participant);
}
initialAssocClazz.participantsAttributes = null; // On force
// ainsi à
// regénérer
// l'objet
initialAssocClazz.participantsClassifiers = null; // On force
// ainsi à
// regénérer
// l'objet
}
}
private boolean contains(Collection coll,
ObjectModelAttributeImpl toFind) {
for (ObjectModelAttribute attribute : coll) {
if (attribute.getName().equals(toFind.getName())) { // Seul le nom
// de l'attribut
// compte
return true;
}
}
return false;
}
private boolean contains(Collection coll, ObjectModelOperationImpl toFind) {
return coll.contains(toFind); // Le equals(...) de
// ObjectModelOperationImpl convient
}
private boolean contains(Collection coll, ObjectModelImplRef toFind) {
return coll.contains(toFind); // Le equals(...) de ObjectModelImplRef
// convient
}
public ObjectModelImplTagValue addTagValue(ObjectModelImplTagValue tagValue) {
if (tagValue == null) {
return new ObjectModelImplTagValue();
}
tagValues.put(tagValue.getName(), tagValue.getValue());
return tagValue;
}
@Override
public Map getTagValues() {
return tagValues;
}
@Override
public String getTagValue(String tagValue) {
return tagValue == null ? null : tagValues.get(tagValue);
}
@Override
public void addTagValue(String tagValue, String value) {
String oldValue = getTagValue(tagValue);
if (StringUtils.isNotEmpty(oldValue) && !oldValue.equals(value)) {
if (log.isWarnEnabled()) {
log.warn("Replace tagValue '" + tagValue + "' (old:" +
oldValue + ", new: " + value + ")");
}
}
tagValues.put(tagValue, value);
}
@Override
public boolean hasTagValue(String tagValue) {
return tagValues.containsKey(tagValue);
}
/**
* Get the extension associated to the reference (unique). Create it if not exist.
*
* @param object type returned
* @param reference unique corresponding to the extension to get
* @param extensionClass class of the extension
* @return the object value for the extension
* @throws ClassCastException when extensionClass is not valid
* @throws RuntimeException when instantiation problem to create new extension
*/
@Override
@SuppressWarnings("unchecked")
public O getExtension(String reference, Class extensionClass) throws RuntimeException {
if (reference == null) {
throw new NullPointerException("reference parameter can not be null in method ObjectModelImpl#getExtension");
}
if (extensionClass == null) {
throw new NullPointerException("extensionClass parameter can not be null in method ObjectModelImpl#getExtension.");
}
Object object = extensions.get(reference);
O result;
if (object != null && !extensionClass.isAssignableFrom(object.getClass())) {
throw new ClassCastException("Invalid cast for " + extensionClass.getName());
}
if (object == null) {
try {
result = extensionClass.newInstance();
} catch (Exception eee) { // IllegalAccessException and InstantiationException
throw new RuntimeException("Unable to create new extension '" + extensionClass.getName() +
"' for '" + reference + "'", eee);
}
extensions.put(reference, result);
} else {
result = (O) object;
}
return result;
}
}