/*
* (c) Copyright 2010-2011 AgileBirds
*
* This file is part of OpenFlexo.
*
* OpenFlexo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenFlexo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.openflexo.foundation.dm;
import java.text.Collator;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.InvalidNameException;
import org.openflexo.foundation.DataModification;
import org.openflexo.foundation.FlexoObservable;
import org.openflexo.foundation.Inspectors;
import org.openflexo.foundation.dm.DMMethod.DMMethodParameter;
import org.openflexo.foundation.dm.DMType.DMTypeTokenizer;
import org.openflexo.foundation.dm.dm.DMAttributeDataModification;
import org.openflexo.foundation.dm.dm.DMEntityClassNameChanged;
import org.openflexo.foundation.dm.dm.DMEntityNameChanged;
import org.openflexo.foundation.dm.dm.EntityDeleted;
import org.openflexo.foundation.dm.dm.MethodRegistered;
import org.openflexo.foundation.dm.dm.MethodUnregistered;
import org.openflexo.foundation.dm.dm.PropertiesReordered;
import org.openflexo.foundation.dm.dm.PropertyRegistered;
import org.openflexo.foundation.dm.dm.PropertyUnregistered;
import org.openflexo.foundation.dm.dm.TranstyperRegistered;
import org.openflexo.foundation.dm.dm.TranstyperUnregistered;
import org.openflexo.foundation.dm.eo.DMEOEntity;
import org.openflexo.foundation.dm.eo.DMEOProperty;
import org.openflexo.foundation.ie.IERegExp;
import org.openflexo.foundation.validation.ValidationError;
import org.openflexo.foundation.validation.ValidationIssue;
import org.openflexo.foundation.validation.ValidationRule;
import org.openflexo.foundation.wkf.FlexoProcess;
import org.openflexo.foundation.xml.FlexoDMBuilder;
import org.openflexo.localization.FlexoLocalization;
/**
* Represents a java entity (class, interface or enum) and its definition
*
* @author sguerin
*
*/
public class DMEntity extends DMObject implements DMGenericDeclaration, DMTypeOwner, Typed {
private static final Logger logger = Logger.getLogger(DMEntity.class.getPackage().getName());
// ===============================================================
// ======================= Instance variables ====================
// ===============================================================
protected String name;
protected String entityPackageName;
protected String entityClassName;
protected DMType _parentType;
protected Vector<DMType> _implementedTypes;
private final Vector<DMEntity> childEntities;
// private Vector<Typed> typedWithThisEntity;
private DMRepository repository;
// List of all properties declared in this entity (hashtable of DMProperty)
private DMPropertyHashtable properties;
// List of all methods declared for this entity (hashtable of DMMethod)
private DMMethodHashtable methods;
private boolean readOnly;
private Date _lastUpdate;
private boolean _isInterface;
private boolean _isEnumeration;
// List of all type variables declared for this entity
private Vector<DMTypeVariable> _typeVariables;
// List of transtypers declared for this entity
private final Vector<DMTranstyper> _declaredTranstypers;
private class DMPropertyHashtable extends Hashtable<String, DMProperty> {
public DMPropertyHashtable() {
super();
}
public DMPropertyHashtable(Hashtable<String, DMProperty> ht) {
super(ht);
}
@Override
public Enumeration<String> keys() {
if (isSerializing()) {
// Order keys in this case
Vector<String> orderedKeys = new Vector<String>();
for (Enumeration<String> en = super.keys(); en.hasMoreElements();) {
orderedKeys.add(en.nextElement());
}
Collections.sort(orderedKeys, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return Collator.getInstance().compare(o1, o2);
}
});
return orderedKeys.elements();
}
return super.keys();
}
}
private class DMMethodHashtable extends Hashtable<String, DMMethod> {
public DMMethodHashtable() {
super();
}
public DMMethodHashtable(Hashtable<String, DMMethod> ht) {
super(ht);
}
@Override
public Enumeration<String> keys() {
if (isSerializing()) {
// Order keys in this case
Vector<String> orderedKeys = new Vector<String>();
for (Enumeration<String> en = super.keys(); en.hasMoreElements();) {
orderedKeys.add(en.nextElement());
}
Collections.sort(orderedKeys, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return Collator.getInstance().compare(o1, o2);
}
});
return orderedKeys.elements();
}
return super.keys();
}
}
// ==========================================================================
// ============================= Constructor
// ================================
// ==========================================================================
/**
* Constructor used during deserialization
*/
public DMEntity(FlexoDMBuilder builder) {
this(builder.dmModel);
initializeDeserialization(builder);
}
/**
* Default constructor
*/
public DMEntity(DMModel dmModel) {
super(dmModel);
properties = new DMPropertyHashtable();
methods = new DMMethodHashtable();
childEntities = new Vector<DMEntity>();
orderedProperties = new Vector<DMProperty>();
accessibleProperties = new Vector<DMProperty>();
orderedMethods = new Vector<DMMethod>();
accessibleMethods = new Vector<DMMethod>();
_typeVariables = new Vector<DMTypeVariable>();
_implementedTypes = new Vector<DMType>();
_declaredTranstypers = new Vector<DMTranstyper>();
}
/**
* Constructor used for dynamic creation
*/
public DMEntity(DMModel dmModel, String name, String packageName, String className, DMType parentType) {
this(dmModel);
this.name = name;
entityPackageName = packageName;
entityClassName = className;
setParentType(parentType, true);
}
@Override
public String getFullyQualifiedName() {
return getEntityPackageName() + "." + getEntityClassName();
}
/**
* Return String uniquely identifying inspector template which must be applied when trying to inspect this object
*
* @return a String value
*/
@Override
public String getInspectorName() {
if (getRepository() == null || getRepository().isReadOnly()) {
return Inspectors.DM.DM_RO_ENTITY_INSPECTOR;
} else {
return Inspectors.DM.DM_ENTITY_INSPECTOR;
}
}
/**
* Return a Vector of embedded DMObjects at this level.
*
* @return a Vector of embedded DMPackage instances
*/
@Override
public Vector<DMObject> getEmbeddedDMObjects() {
Vector<DMObject> returned = new Vector<DMObject>();
returned.addAll(getOrderedChildren());
return returned;
}
@Override
public String getLocalizedName() {
return getEntityClassName() + getTypesVariablesAsString();
}
@Override
public String getName() {
return name;
}
public final String getFullQualifiedName() {
return getPackage() == null || getPackage().isDefaultPackage() ? getEntityClassName() : getPackage().getName() + "."
+ getEntityClassName();
}
@Override
public void setName(String newName) throws InvalidNameException {
if (!isDeserializing() && (newName == null || !DMRegExp.ENTITY_NAME_PATTERN.matcher(newName).matches())) {
throw new InvalidNameException(newName + " is not a valid name.");
}
if (name == null || !name.equals(newName)) {
String oldName = name;
name = newName;
setChanged();
notifyObservers(new DMEntityNameChanged(this, oldName, newName));
if (getPackage() != null) {
getPackage().notifyReordering(this);
}
}
}
@Override
public boolean isDeletable() {
if (this.equals(getDMModel().getWORepository().getCustomApplicationEntity())) {
return false;
}
if (this.equals(getDMModel().getWORepository().getCustomSessionEntity())) {
return false;
}
if (this.equals(getDMModel().getWORepository().getCustomDirectActionEntity())) {
return false;
}
if (this.equals(getDMModel().getWORepository().getCustomComponentEntity())) {
return false;
}
if (this.equals(getDMModel().getProcessBusinessDataRepository().getProcessBusinessDataEntity())) {
return false;
}
return !isDeleted() && getRepository() != null && !getRepository().isReadOnly();
}
public String getEntityClassName() {
return entityClassName;
}
public String getClassName() {
return getEntityClassName();
}
/*
* protected void updateTypeObject(String oldClassName,String newClassName) { if(isDeserializing())return; Enumeration<Typed> en =
* getTypedWithThisEntity().elements(); while(en.hasMoreElements()){
* en.nextElement().updateTypeClassNameChange(oldClassName,newClassName); } }
*/
public void setEntityClassName(String newEntityClassName) throws DuplicateClassNameException, InvalidNameException {
/* if (entityClassName == null) {
entityClassName = newEntityClassName;
updateTypeObject(null,newEntityClassName);
return;
}*/
if (!isDeserializing() && (newEntityClassName == null || !DMRegExp.ENTITY_NAME_PATTERN.matcher(newEntityClassName).matches())) {
logger.warning("Invalid name: " + newEntityClassName);
throw new InvalidNameException();
}
if (entityClassName == null || !entityClassName.equals(newEntityClassName)) {
if (!isDeserializing() && getDMModel().getDMEntity(getEntityPackageName(), newEntityClassName) != null) {
throw new DuplicateClassNameException(getEntityPackageName() + "." + newEntityClassName);
}
DMRepository containerRepository = getRepository();
if (containerRepository != null && entityClassName != null) {
containerRepository.unregisterEntity(this, false);
}
String oldEntityClassName = entityClassName;
entityClassName = newEntityClassName;
// updateTypeObject(oldEntityClassName,newEntityClassName);
if (containerRepository != null) {
containerRepository.registerEntity(this);
}
setChanged();
notifyObservers(new DMEntityClassNameChanged(this, oldEntityClassName, newEntityClassName));
}
}
public boolean isInDefaultPackage() {
return getEntityPackageName() != null && getEntityPackageName().equals(getRepository().getDefaultPackage().getName())
&& !isPrimitiveType();
}
public String getEntityPackageName() {
if (entityPackageName == null) {
if (getRepository() != null) {
entityPackageName = getRepository().getDefaultPackage().getName();
}
/*
* else { if (logger.isLoggable(Level.WARNING)) logger.warning("Could not determine default package since repository was not set
* !"); }
*/
}
return entityPackageName;
}
public void setEntityPackageName(String anEntityPackageName) {
String oldEntityPackageName = entityPackageName;
if (oldEntityPackageName == null && anEntityPackageName == null) {
return;
}
if (entityPackageName != null && entityPackageName.equals(DMPackage.DEFAULT_PACKAGE_NAME) && anEntityPackageName == null) {
return;
}
if (oldEntityPackageName == null || anEntityPackageName == null || !oldEntityPackageName.equals(anEntityPackageName)) {
entityPackageName = anEntityPackageName;
setChanged();
notifyObservers(new DMAttributeDataModification("entityPackageName", oldEntityPackageName, entityPackageName));
}
}
public void moveToPackage(String anEntityPackageName) {
String oldEntityPackageName = entityPackageName;
String oldFullyQualifiedName = getFullyQualifiedName();
if (oldEntityPackageName == null && anEntityPackageName == null) {
return;
}
if (entityPackageName != null && entityPackageName.equals(DMPackage.DEFAULT_PACKAGE_NAME) && anEntityPackageName == null) {
return;
}
if (oldEntityPackageName == null || anEntityPackageName == null || !oldEntityPackageName.equals(anEntityPackageName)) {
// logger.info("Package change from "+oldEntityPackageName+" to "+anEntityPackageName+" count="+count);
if (!isDeserializing()) {
getPackage().unregisterEntity(this);
// getDMModel().unregisterEntity(this);
}
entityPackageName = anEntityPackageName;
if (!isDeserializing()) {
getPackage().registerEntity(this);
// getDMModel().registerEntity(this);
String newFullyQualifiedName = getFullyQualifiedName();
getRepository().changePackage(this, oldFullyQualifiedName, newFullyQualifiedName);
}
setChanged();
notifyObservers(new DMAttributeDataModification("entityPackageName", oldEntityPackageName, entityPackageName));
}
}
public DMPackage getPackage() {
if (getRepository() != null) {
return getRepository().packageForEntity(this);
}
return null;
}
public String getPathForPackage() {
return getPackage().getRelativePath();
}
@Override
public DMType getType() {
return getParentType();
}
@Override
public void setType(DMType type) {
setParentType(type, true);
}
public DMType getParentType() {
/*
* if (_parentType==null && parentTypeAsString!=null) {
* setParentType(getDMModel().getDmTypeConverter().convertFromString(parentTypeAsString), false); parentTypeAsString = null; }
*/
return _parentType;
}
public void setParentType(DMType parentType) {
setParentType(parentType, true);
}
public void setParentType(DMType parentType, boolean notify) {
if (logger.isLoggable(Level.FINE)) {
logger.fine("setParentType in " + name + " with " + (parentType == null ? "null" : parentType.getStringRepresentation()));
}
if (parentType == null && _parentType != null || parentType != null && !parentType.equals(_parentType)) {
DMType oldParentType = _parentType;
if (oldParentType != null) {
oldParentType.removeFromTypedWithThisType(this);
DMEntity oldParentEntity = oldParentType.getBaseEntity();
if (oldParentEntity != null) {
oldParentEntity.removeFromChildEntities(this);
}
}
_parentType = parentType;
if (_parentType != null) {
_parentType.setOwner(this);
_parentType.addToTypedWithThisType(this);
DMEntity newParentEntity = _parentType.getBaseEntity();
if (newParentEntity != null) {
newParentEntity.addToChildEntities(this);
}
}
if (notify) {
setChanged();
notifyObservers(new DMAttributeDataModification("parentType", oldParentType, parentType));
}
}
}
/*
* private String parentTypeAsString;
*
* public String getParentTypeAsString() { if (getParentType()!=null) return
* getDMModel().getDmTypeConverter().convertToString(getParentType()); else return null; }
*
* public void setParentTypeAsString(String parentType) { parentTypeAsString = parentType; }
*/
public final DMEntity getParentBaseEntity() {
if (getParentType() != null) {
return getParentType().getBaseEntity();
}
return null;
}
public final void setParentBaseEntity(DMEntity aParentEntity) {
setType(DMType.makeResolvedDMType(aParentEntity));
}
public Vector<DMEntity> getChildEntities() {
return childEntities;
}
public void addToChildEntities(DMEntity anEntity) {
childEntities.add(anEntity);
}
public void removeFromChildEntities(DMEntity anEntity) {
childEntities.remove(anEntity);
}
/*
* public Vector<Typed> getTypedWithThisEntity() { return typedWithThisEntity; }
*
* public void addToTypedWithThisType(Typed aTyped) { if (aTyped.getType().getBaseEntity() == this) { typedWithThisEntity.add(aTyped); }
* else { if (logger.isLoggable(Level.WARNING)) logger.warning("Type doesn' match !"); } }
*
* public void removeFromTypedWithThisType(Typed aTyped) { typedWithThisEntity.remove(aTyped); }
*/
// ===========================================================
// ===================== FlexoObserver =======================
// ===========================================================
@Override
public void update(FlexoObservable observable, DataModification dataModification) {
if (dataModification instanceof TypeResolved && ((TypeResolved) dataModification).getType() == _parentType) {
DMEntity newParentEntity = _parentType.getBaseEntity();
if (newParentEntity != null) {
if (logger.isLoggable(Level.FINE)) {
logger.fine("Parent type " + _parentType + " decoded for " + this);
}
newParentEntity.addToChildEntities(this);
}
} else if (dataModification instanceof EntityDeleted && getParentType() != null && observable == getParentType().getBaseEntity()) {
DMEntity parent = getParentBaseEntity();
while (parent != null && parent.isDeleted()) {
parent = parent.getParentBaseEntity();
}
if (parent != this && parent != null) {
setParentType(DMType.makeResolvedDMType(parent));
} else {
setParentType(null);
}
} else {
super.update(observable, dataModification);
}
}
public DMRepository getRepository() {
return repository;
}
public void setRepository(DMRepository repository) {
setRepository(repository, true);
}
public void setRepository(DMRepository repository, boolean notify) {
this.repository = repository;
if (notify) {
setChanged();
}
}
public boolean getIsReadOnly() {
return readOnly || getRepository() != null && getRepository().isReadOnly();
}
public void setIsReadOnly(boolean readOnly) {
this.readOnly = readOnly;
setChanged();
}
public Hashtable<String, DMMethod> getMethods() {
return methods;
}
/**
* Return a vector of up-to-date and ordered DMMethod vector representing all methods declared for this entity
*
* @return a Vector<DMMethod>
*/
public Vector<DMMethod> getDeclaredMethods() {
return getOrderedMethods();
}
/**
* Return a vector of accessible DMMethods. An accessible mehod is defined as a method defined in this entity of somewhere in an
* ancestor entity.
*
* @return a Vector of DMMethod objects
*/
public Vector<DMMethod> getAccessibleMethods() {
if (methodsNeedsReordering) {
reorderMethods();
}
return accessibleMethods;
}
public void setMethods(Hashtable<String, DMMethod> methods) {
this.methods = new DMMethodHashtable(methods);
setMethodsNeedsReordering();
setChanged();
}
public void setMethodForKey(DMMethod method, String methodSignature) {
if (method._getRegisteredWithSignature() != null && !method._getRegisteredWithSignature().equals(methodSignature)
&& methods.get(method._getRegisteredWithSignature()) != null) {
removeMethodWithKey(method._getRegisteredWithSignature());
}
method.setEntity(this);
if (logger.isLoggable(Level.FINE)) {
logger.fine("Entity: " + toString() + " setMethodForKey() with " + method.getSignature());
}
methods.put(methodSignature, method);
method._setRegisteredWithSignature(methodSignature);
setMethodsNeedsReordering();
}
@Override
public void finalizeDeserialization(Object builder) {
super.finalizeDeserialization(builder);
}
public void removeMethodWithKey(String methodSignature) {
if (logger.isLoggable(Level.FINE)) {
logger.fine("Entity: " + toString() + " removeMethodWithKey() with " + methodSignature);
}
methods.remove(methodSignature);
setMethodsNeedsReordering();
setChanged();
}
/**
* Register method for this entity
*
* @param method
* : the method to register
* @return true if method has been effectively registered, false otherwise
*/
public boolean registerMethod(DMMethod method) {
return registerMethod(method, true);
}
/**
* Register method for this entity
*
* @param method
* : the method to register
* @param notify
* : true if notification has to be forwarded
* @return true if method has been effectively registered, false otherwise
*/
public boolean registerMethod(DMMethod method, boolean notify) {
if (methods.get(method.getSignature()) == null) {
if (logger.isLoggable(Level.FINE)) {
logger.fine("Register method " + method.getSignature());
}
setMethodForKey(method, method.getSignature());// Sets the entity
// as well
if (notify) {
setChanged();
notifyObservers(new MethodRegistered(method));
}
method._isRegistered = true;
return true;
} else if (method != methods.get(method.getSignature())) {
if (logger.isLoggable(Level.WARNING)) {
logger.warning("Trying to redefine method " + method.getSignature() + ": operation not allowed !");
}
}
return false;
}
/**
* Un-register method for this entity
*
* @param method
* : the method to unregister
* @return true if method has been effectively un-registered, false otherwise
*/
public boolean unregisterMethod(DMMethod method) {
return unregisterMethod(method, true);
}
/**
* Un-register method for this entity
*
* @param method
* : the method to unregister
* @param notify
* : true if notification has to be forwarded
* @return true if method has been effectively un-registered, false otherwise
*/
public boolean unregisterMethod(DMMethod method, boolean notify) {
method._isRegistered = false;
if (methods.get(method.getSignature()) != null) {
method.setEntity(null);
removeMethodWithKey(method.getSignature());
if (notify) {
setChanged();
notifyObservers(new MethodUnregistered(method));
}
return true;
}
return false;
}
/**
* Return method whose signature matches 'methodSignature' explicitely declared in this entity
*
* @param propertyName
* @return
*/
public DMMethod getDeclaredMethod(String methodSignature) {
return methods.get(methodSignature);
}
/**
* Return method whose signature matches 'methodSignature' accessible from this entity. This method allows to access inherited methods
* from parent classes.
*
* @param methodSignature
* @return
*/
public DMMethod getMethod(String methodSignature) {
DMMethod returned = getDeclaredMethod(methodSignature);
if (returned == null && getParentBaseEntity() != null) {
return getParentBaseEntity().getMethod(methodSignature);
} else {
return returned;
}
}
/**
* Return methods with name 'methodName'
*
* @param methodSignature
* @return a Vector of DMMethod objects
*/
public Vector<DMMethod> getDeclaredMethodNamed(String methodName) {
Vector<DMMethod> returned = new Vector<DMMethod>();
for (Enumeration en = methods.elements(); en.hasMoreElements();) {
DMMethod next = (DMMethod) en.nextElement();
if (next.getName().equals(methodName)) {
returned.add(next);
}
}
return returned;
}
public Hashtable<String, DMProperty> getProperties() {
return properties;
}
/**
* Return a vector of up-to-date and reordered DMProperty
*
* @return
*/
public Vector<DMProperty> getOrderedSingleProperties() {
return getOrderedProperties();
}
/**
* Return a vector of up-to-date and ordered DMProperty vector representing all properties declared for this entity
*
* @return a Vector<DMProperty>
*/
public Vector<DMProperty> getDeclaredProperties() {
return getOrderedProperties();
}
/**
* Return a vector of accessible DMProperties An accessible property is defined as a property defined in this entity of somewhere in an
* ancestor entity. If this entity is a DMEOProperty, it must be a class property.
*
* @return
*/
public Vector<DMProperty> getAccessibleProperties() {
if (propertiesNeedsReordering) {
reorderProperties();
}
return accessibleProperties;
}
public void setProperties(Hashtable<String, DMProperty> properties) {
this.properties = new DMPropertyHashtable(properties);
setPropertiesNeedsReordering();
setChanged();
}
public void setPropertyForKey(DMProperty property, String propertyName) {
property.setEntity(this);
properties.put(propertyName, property);
setPropertiesNeedsReordering();
}
public void removePropertyWithKey(String propertyName) {
removePropertyWithKey(propertyName, true);
}
public void removePropertyWithKey(String propertyName, boolean notify) {
properties.remove(propertyName);
if (notify) {
setPropertiesNeedsReordering();
}
}
/**
* Register property for this entity
*
* @param property
* : the property to register
* @return true if property has been effectively registered, false otherwise
*/
public boolean registerProperty(DMProperty property, boolean isBindable) {
return registerProperty(property, true, isBindable);
}
/**
* Register property for this entity
*
* @param property
* : the property to register
* @param notify
* : true if notification has to be forwarded
* @return true if property has been effectively registered, false otherwise
*/
public boolean registerProperty(DMProperty property, boolean notify, boolean isBindable) {
if (properties.get(property.getName()) == null) {
if (logger.isLoggable(Level.FINE)) {
logger.fine("Register property " + property.getName());
}
if (this instanceof ComponentDMEntity) {
((ComponentDMEntity) this).setPropertyForKey(property, property.getName(), isBindable);// Sets the entity
} else {
setPropertyForKey(property, property.getName());// Sets the entity
}
// as well
if (notify) {
setChanged();
notifyObservers(new PropertyRegistered(property));
}
return true;
} else if (property != properties.get(property.getName())) {
if (logger.isLoggable(Level.WARNING)) {
logger.warning("You are trying to redefine property " + property.getName() + "(" + property.getType() + ") "
+ " but property " + property.getName() + "(" + properties.get(property.getName()).getType()
+ ") is already existing");
}
}
return false;
}
/**
* Un-register property for this entity
*
* @param property
* : the property to unregister
* @return true if property has been effectively un-registered, false otherwise
*/
public boolean unregisterProperty(DMProperty property) {
return unregisterProperty(property, true);
}
/**
* Un-register property for this entity
*
* @param property
* : the property to unregister
* @param notify
* : true if notification has to be forwarded
* @return true if property has been effectively un-registered, false otherwise
*/
public boolean unregisterProperty(DMProperty property, boolean notify) {
if (properties.get(property.getName()) != null) {
property.setEntity(null);
removePropertyWithKey(property.getName(), notify);
if (notify) {
setChanged();
notifyObservers(new PropertyUnregistered(property));
}
return true;
}
return false;
}
/**
* Return property named 'propertyName' explicitely declared in this entity
*
* @param propertyName
* @return
*/
public DMProperty getDeclaredProperty(String propertyName) {
return properties.get(propertyName);
}
/**
* Return property named 'propertyName' accessible from this entity. This method allows to access inherited properties from parent
* classes.
*
* @param propertyName
* @return
*/
public DMProperty getProperty(String propertyName) {
DMProperty returned = getDeclaredProperty(propertyName);
if (returned == null && getParentBaseEntity() != null) {
return getParentBaseEntity().getProperty(propertyName);
} else {
return returned;
}
}
/**
* Returns boolean indicating if this entity is an ancestor of supplied entity. Returns true if entity equals this entity, or if this
* entity is a parent of supplied entity (parent class or parent interface)
*
* Note that both 'extends' and 'implements' schemes are implemented by this method
*
* @param entity
* @return a boolean
*/
public boolean isAncestorOf(DMEntity entity) {
if (entity == null) {
return false;
}
if (entity == this) {
return true;
}
if (this == getDMModel().getDMEntity(Object.class)/* && (!(entity instanceof JDKPrimitive))*/) {
return true;
}
if (entity.getParentBaseEntity() != null) {
if (isAncestorOf(entity.getParentBaseEntity())) {
return true;
}
}
for (DMType implementedType : entity.getImplementedTypes()) {
if (isAncestorOf(implementedType.getBaseEntity())) {
return true;
}
}
return false;
}
/**
* Returns most direct ancestor of supplied entity, on it's way to this type as ancestor, assuming this type is an ancestor of supplied
* entity
*
* @param entity
* @return
*/
public DMType getClosestAncestorOf(DMEntity entity) {
if (entity == null) {
return null;
}
if (entity == this) {
return DMType.makeResolvedDMType(entity);
}
if (this == getDMModel().getDMEntity(Object.class)/* && (!(entity instanceof JDKPrimitive))*/) {
return DMType.makeResolvedDMType(getDMModel().getDMEntity(Object.class));
}
if (entity.getParentBaseEntity() != null) {
if (isAncestorOf(entity.getParentBaseEntity())) {
return entity.getParentType();
}
}
for (DMType implementedType : entity.getImplementedTypes()) {
if (isAncestorOf(implementedType.getBaseEntity())) {
return implementedType;
}
}
return null;
}
public boolean isDMEOEntity() {
return this instanceof DMEOEntity;
}
public boolean getIsEnumeration() {
return _isEnumeration;
}
public void setIsEnumeration(boolean isEnumeration) {
if (_isEnumeration != isEnumeration) {
_isEnumeration = isEnumeration;
setChanged();
notifyObservers(new DMAttributeDataModification("isEnumeration", !isEnumeration, isEnumeration));
}
}
public boolean getIsInterface() {
return _isInterface;
}
public void setIsInterface(boolean isInterface) {
if (_isInterface != isInterface) {
_isInterface = isInterface;
setChanged();
notifyObservers(new DMAttributeDataModification("isInterface", !isInterface, isInterface));
}
}
public boolean getIsNormalClass() {
return !getIsEnumeration() && !getIsInterface();
}
@Override
public void delete() {
Vector<DMProperty> propertiesToDelete = new Vector<DMProperty>();
propertiesToDelete.addAll(getOrderedProperties());
for (Enumeration en = propertiesToDelete.elements(); en.hasMoreElements();) {
DMProperty next = (DMProperty) en.nextElement();
next.delete();
}
DMPackage package1 = getPackage();
if (getRepository() != null) {
getRepository().unregisterEntity(this);
}
if (package1 != null) {
package1.unregisterEntity(this);
// // Handles 'parent' relations
// Vector<DMEntity> entitiesToUpdate = new Vector<DMEntity>();
// entitiesToUpdate.addAll(getChildEntities());
// for (Enumeration en = entitiesToUpdate.elements(); en.hasMoreElements();) {
// DMEntity next = (DMEntity) en.nextElement();
// next.setParentType(null, true);
// if (logger.isLoggable(Level.FINE))
// logger.fine("Sets " + next + " to have null parent");
// }
}
// Handles 'typedWithThisType' relations
/*
* Vector<Typed> propertiesToUpdate = new Vector<Typed>(); propertiesToUpdate.addAll(getTypedWithThisEntity()); for (Enumeration en
* = propertiesToUpdate.elements(); en.hasMoreElements();) { Typed next = (Typed) en.nextElement(); next.setType(null); if
* (logger.isLoggable(Level.FINE)) logger.fine("Sets " + next + " to have null type"); }
*/
super.delete();
setChanged();
notifyObservers(new EntityDeleted(this));
deleteObservers();
name = null;
entityPackageName = null;
entityClassName = null;
_parentType = null;
repository = null;
}
public DMProperty getDMProperty(String aPropertyName) {
return getProperties().get(aPropertyName);
}
public String getStringRepresentation() {
String returned = "Name = " + getName() + " inherits from " + (getParentType() != null ? getParentType().getName() : "none") + "\n";
for (Enumeration e = properties.elements(); e.hasMoreElements();) {
DMProperty property = (DMProperty) e.nextElement();
returned += " " + property.getStringRepresentation() + "\n";
}
return returned;
}
private Vector<DMProperty> orderedProperties;
private Vector<DMProperty> accessibleProperties;
protected boolean propertiesNeedsReordering = true;
private Vector<DMMethod> orderedMethods;
private Vector<DMMethod> accessibleMethods;
protected boolean methodsNeedsReordering = true;
private Vector<DMObject> orderedChildren;
public void setPropertiesNeedsReordering() {
propertiesNeedsReordering = true;
for (Enumeration en = getChildEntities().elements(); en.hasMoreElements();) {
((DMEntity) en.nextElement()).setPropertiesNeedsReordering();
}
orderedChildren = null;
setChanged();
notifyObservers(new PropertiesReordered(this));
}
private void setMethodsNeedsReordering() {
methodsNeedsReordering = true;
for (Enumeration en = getChildEntities().elements(); en.hasMoreElements();) {
((DMEntity) en.nextElement()).setMethodsNeedsReordering();
}
orderedChildren = null;
}
/**
* Return a vector of up-to-date and reordered DMProperty
*
* @return
*/
public synchronized Vector<DMProperty> getOrderedProperties() {
if (propertiesNeedsReordering) {
reorderProperties();
}
return orderedProperties;
}
/**
* Return a vector of up-to-date and reordered DMMethod
*
* @return a Vector of DMMethod objects
*/
public synchronized Vector<DMMethod> getOrderedMethods() {
if (methodsNeedsReordering) {
reorderMethods();
}
return orderedMethods;
}
@Override
public synchronized Vector<DMObject> getOrderedChildren() {
if (orderedChildren == null) {
orderedChildren = new Vector<DMObject>();
orderedChildren.addAll(getOrderedProperties());
orderedChildren.addAll(getOrderedMethods());
orderedChildren.addAll(getDeclaredTranstypers());
}
return orderedChildren;
}
public synchronized DMProperty getOrderedPropertyNamed(String name) {
Enumeration en = getOrderedSingleProperties().elements();
while (en.hasMoreElements()) {
DMProperty p = (DMProperty) en.nextElement();
if (p.name.equals(name)) {
return p;
}
}
return null;
}
public synchronized DMMethod getOrderedMethodNamed(String name) {
Enumeration en = getOrderedMethods().elements();
while (en.hasMoreElements()) {
DMMethod m = (DMMethod) en.nextElement();
if (m.name.equals(name)) {
return m;
}
}
return null;
}
protected synchronized void reorderMethods() {
if (methodsNeedsReordering) {
if (orderedMethods != null) {
orderedMethods.removeAllElements();
} else {
orderedMethods = new Vector<DMMethod>();
}
orderedMethods.addAll(getMethods().values());
Collections.sort(orderedMethods, methodComparator);
if (accessibleMethods != null) {
accessibleMethods.removeAllElements();
} else {
accessibleMethods = new Vector<DMMethod>();
}
for (Enumeration en = getMethods().elements(); en.hasMoreElements();) {
DMMethod method = (DMMethod) en.nextElement();
accessibleMethods.add(method);
}
DMEntity currentParent = getParentBaseEntity();
while (currentParent != null) {
for (Enumeration en = currentParent.getAccessibleMethods().elements(); en.hasMoreElements();) {
DMMethod method = (DMMethod) en.nextElement();
boolean isOverriding = false;
for (int i = 0; i < accessibleMethods.size() && !isOverriding; i++) {
DMMethod temp = accessibleMethods.elementAt(i);
if (temp.overrides(method)) {
// if (logger.isLoggable(Level.INFO)) logger.info
// ("Property "+temp+" overrides "+property);
isOverriding = true;
}
}
if (!isOverriding) {
accessibleMethods.add(method);
}
}
currentParent = currentParent.getParentBaseEntity();
}
Collections.sort(accessibleMethods, methodComparator);
methodsNeedsReordering = false;
}
}
protected synchronized void reorderProperties() {
if (propertiesNeedsReordering) {
if (orderedProperties != null) {
orderedProperties.removeAllElements();
} else {
orderedProperties = new Vector<DMProperty>();
}
orderedProperties.addAll(getProperties().values());
Collections.sort(orderedProperties, propertyComparator);
if (accessibleProperties != null) {
accessibleProperties.removeAllElements();
} else {
accessibleProperties = new Vector<DMProperty>();
}
for (Enumeration en = getProperties().elements(); en.hasMoreElements();) {
DMProperty property = (DMProperty) en.nextElement();
if (property instanceof DMEOProperty) {
if (((DMEOProperty) property).getIsClassProperty()) {
accessibleProperties.add(property);
}
} else {
accessibleProperties.add(property);
}
}
DMEntity currentParent = getParentBaseEntity();
while (currentParent != null) {
for (Enumeration en = currentParent.getAccessibleProperties().elements(); en.hasMoreElements();) {
DMProperty property = (DMProperty) en.nextElement();
boolean isOverriding = false;
for (int i = 0; i < accessibleProperties.size() && !isOverriding; i++) {
DMProperty temp = accessibleProperties.elementAt(i);
if (temp.overrides(property)) {
// if (logger.isLoggable(Level.INFO)) logger.info
// ("Property "+temp+" overrides "+property);
isOverriding = true;
}
}
if (!isOverriding) {
accessibleProperties.add(property);
}
}
currentParent = currentParent.getParentBaseEntity();
}
Collections.sort(accessibleProperties, propertyComparator);
propertiesNeedsReordering = false;
}
}
protected static final PropertyComparator propertyComparator = new PropertyComparator();
/**
* Used to sort properties according to name alphabetic ordering
*
* @author sguerin
*
*/
protected static class PropertyComparator implements Comparator<DMProperty> {
/**
* Implements
*
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
@Override
public int compare(DMProperty o1, DMProperty o2) {
String s1 = o1.getName();
String s2 = o2.getName();
if (s1 != null && s2 != null) {
return Collator.getInstance().compare(s1, s2);
} else {
return 0;
}
}
}
protected static final MethodComparator methodComparator = new MethodComparator();
/**
* Used to sort methods according to signature alphabetic ordering
*
* @author sguerin
*
*/
protected static class MethodComparator implements Comparator<DMMethod> {
/**
* Implements
*
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
@Override
public int compare(DMMethod o1, DMMethod o2) {
String s1 = o1.getSignature();
String s2 = o2.getSignature();
if (s1 != null && s2 != null) {
return Collator.getInstance().compare(s1, s2);
} else {
return 0;
}
}
}
@Override
public DMObject getParent() {
return getPackage();
}
@Override
public void notifyReordering(DMObject cause) {
propertiesNeedsReordering = true;
methodsNeedsReordering = true;
super.notifyReordering(cause);
}
/**
* Overrides getClassNameKey
*
* @see org.openflexo.foundation.FlexoModelObject#getClassNameKey()
*/
@Override
public String getClassNameKey() {
return "dm_entity";
}
public DMProperty createDMProperty(String name, DMType type, DMPropertyImplementationType implementationType) {
DMProperty newProperty = new DMProperty(getProject().getDataModel(), name, type, DMCardinality.SINGLE, false, true,
implementationType);
registerProperty(newProperty, true);
return newProperty;
}
/*
* public void createBindingVariablesFromEntity(Bindable bindable, BindingModel bdmodel){ Enumeration<DMProperty> en =
* getProperties().elements(); DMProperty p = null; while(en.hasMoreElements()){ p = en.nextElement(); BindingVariable newBV = new
* BindingVariable(bindable, getDMModel(), ""); newBV.setType(p.getType()); newBV.setVariableName(p.getName());
* bdmodel.addToBindingVariables(newBV); } }
*/
/**
* This date is use to perform fine tuning resource dependancies computing
*
* @return
*/
@Override
public Date getLastUpdate() {
if (_lastUpdate == null) {
_lastUpdate = lastMemoryUpdate();
}
if (_lastUpdate == null) {
_lastUpdate = super.getLastUpdate();
}
return _lastUpdate;
}
public void setLastUpdate(Date lastUpdate) {
_lastUpdate = lastUpdate;
}
@Override
public void setIsModified() {
if (ignoreNotifications()) {
return;
}
_lastUpdate = null;
super.setIsModified();
// Do this to reset dependant resources cache, in order to get up-to_date
// needsGeneration information on generated resources
if (getXMLResourceData() != null && getXMLResourceData().getFlexoResource() != null) {
getXMLResourceData().getFlexoResource().notifyResourceStatusChanged();
}
}
public boolean hasCreatorProperty() {
return getProperty("creator") != null;
}
public Collection<DMProperty> getPropertiesExcludingEOTypes() {
Vector<DMProperty> reply = new Vector<DMProperty>();
Enumeration<DMProperty> en = getProperties().elements();
DMProperty p = null;
while (en.hasMoreElements()) {
p = en.nextElement();
if (p.getType() != null && !(p.getType().getBaseEntity() instanceof DMEOEntity)) {
reply.add(p);
}
}
return reply;
}
public Collection<DMProperty> getPropertiesEOTypesOnly() {
Vector<DMProperty> reply = new Vector<DMProperty>();
Enumeration<DMProperty> en = getProperties().elements();
DMProperty p = null;
while (en.hasMoreElements()) {
p = en.nextElement();
if (p.getType() != null && p.getType().getBaseEntity() instanceof DMEOEntity) {
reply.add(p);
}
}
return reply;
}
public boolean isVoid() {
return this == getDMModel().getEntityNamed("void");
}
public String getNiceRelationshipNameToMe() {
StringBuffer reply = new StringBuffer();
boolean isPrefixRemoved = false;
for (int i = 0; i < getName().length(); i++) {
if (!isPrefixRemoved && i + 1 < getName().length()) {
if (Character.isUpperCase(getName().charAt(i + 1))) {
// switch this char
} else {
isPrefixRemoved = true;
reply.append(Character.toLowerCase(getName().charAt(i)));
}
} else {
reply.append(getName().charAt(i));
}
}
return reply.toString();
}
public boolean isBusinessDataClass() {
if (getProject().getAllLocalFlexoProcesses() != null) {
Enumeration<FlexoProcess> en = getProject().getAllLocalFlexoProcesses().elements();
while (en.hasMoreElements()) {
if (this.equals(en.nextElement().getBusinessDataType())) {
return true;
}
}
}
return false;
}
public boolean isPrimitiveType() {
return getPackage().isDefaultPackage() && getRepository() == getDMModel().getJDKRepository();
}
public boolean isBooleanType() {
return getName().toLowerCase().equals("boolean");
}
/**
* Overrides isNameValid
*
* @see org.openflexo.foundation.dm.DMObject#isNameValid()
*/
@Override
public boolean isNameValid() {
return getName() != null && getName().matches(IERegExp.JAVA_CLASS_NAME_REGEXP);
}
// ===================================================================
// ==================== Type variables management ====================
// ===================================================================
@Override
public Vector<DMTypeVariable> getTypeVariables() {
return _typeVariables;
}
public void setTypeVariables(Vector<DMTypeVariable> typeVariables) {
_typeVariables = typeVariables;
setChanged();
}
public void addToTypeVariables(DMTypeVariable typeVariable) {
_typeVariables.add(typeVariable);
typeVariable.setEntity(this);
setChanged();
}
public void removeFromTypeVariables(DMTypeVariable typeVariable) {
_typeVariables.remove(typeVariable);
setChanged();
}
public DMTypeVariable createNewTypeVariable() throws DuplicateMethodSignatureException {
DMTypeVariable newTypeVariable = new DMTypeVariable(getDMModel(), this);
newTypeVariable.setName("X");
newTypeVariable.setBounds("");
newTypeVariable.setDescription(FlexoLocalization.localizedForKey("no_description"));
addToTypeVariables(newTypeVariable);
return newTypeVariable;
}
public void deleteTypeVariable(DMTypeVariable typeVariable) throws DuplicateMethodSignatureException {
removeFromTypeVariables(typeVariable);
}
public boolean isTypeVariableAddable(DMTypeVariable typeVariable) {
return !getIsReadOnly();
}
public boolean isTypeVariableDeletable(DMTypeVariable typeVariable) {
return !getIsReadOnly();
}
public String getTypesVariablesAsString() {
if (getTypeVariables().size() == 0) {
return "";
}
StringBuffer sb = new StringBuffer();
sb.append("<");
boolean isFirst = true;
for (DMTypeVariable tv : getTypeVariables()) {
sb.append((isFirst ? "" : ",") + tv.getName());
isFirst = false;
}
sb.append(">");
return sb.toString();
}
public static class DMTypeVariable extends DMObject {
@SuppressWarnings("hiding")
private static final Logger logger = Logger.getLogger(DMEntity.DMTypeVariable.class.getPackage().getName());
private DMEntity _entity;
private String _name;
private String _bounds;
/**
* Constructor used during deserialization
*/
public DMTypeVariable(FlexoDMBuilder builder) {
this(builder.dmModel);
initializeDeserialization(builder);
}
/**
* Default constructor
*/
public DMTypeVariable(DMModel dmModel) {
super(dmModel);
}
/**
* Constructor used for dynamic creation
*/
public DMTypeVariable(DMModel dmModel, DMEntity entity) {
this(dmModel);
this._entity = entity;
}
public void update(DMTypeVariable typeVariable) {
// Name is supposed to be the same, but check anyway
if (!getName().equals(typeVariable.getName())) {
if (logger.isLoggable(Level.FINE)) {
logger.fine("Update name");
}
_name = typeVariable.getName();
} else {
if (logger.isLoggable(Level.FINE)) {
logger.fine("Name is up-to-date");
}
}
// Description
if (getDescription() == null && typeVariable.getDescription() != null
|| !getDescription().equals(typeVariable.getDescription())) {
if (logger.isLoggable(Level.FINE)) {
logger.fine("Update description");
}
setDescription(typeVariable.getDescription());
} else {
if (logger.isLoggable(Level.FINE)) {
logger.fine("Description is up-to-date");
}
}
}
@Override
public String getName() {
return _name;
}
@Override
public void setName(String name) {
_name = name;
}
@Override
public boolean isDeletable() {
return _entity.isDeletable();
}
public DMEntity getEntity() {
return _entity;
}
public void setEntity(DMEntity entity) {
_entity = entity;
}
@Override
public String getFullyQualifiedName() {
if (getEntity() != null) {
return getEntity().getFullyQualifiedName() + ".TV." + getName();
}
return "NULL." + getName();
}
@Override
public Vector<? extends DMObject> getOrderedChildren() {
return EMPTY_VECTOR;
}
@Override
public DMEntity getParent() {
return getEntity();
}
/**
* Return null since parameter is never inspected by its own
*
* @return null
*/
@Override
public String getInspectorName() {
return null;
}
/**
* Return a Vector of embedded DMObjects at this level.
*
* @return null
*/
@Override
public Vector<DMObject> getEmbeddedDMObjects() {
return EMPTY_VECTOR;
}
/**
* Overrides getClassNameKey
*
* @see org.openflexo.foundation.FlexoModelObject#getClassNameKey()
*/
@Override
public String getClassNameKey() {
return "dm_type_variable";
}
public String getBounds() {
return _bounds;
}
public void setBounds(String bounds) {
_bounds = bounds;
}
}
// ===================================================================
// =============== Implemented types management ======================
// ===================================================================
public Vector<DMType> getImplementedTypes() {
return _implementedTypes;
}
public void setImplementedTypes(Vector<DMType> implementedTypes) {
_implementedTypes = implementedTypes;
setChanged();
}
public void addToImplementedTypes(DMType aType) {
if (aType == null) {
if (logger.isLoggable(Level.WARNING)) {
logger.warning("Attempt to add null type");
}
return;
}
_implementedTypes.add(aType);
aType.setOwner(this);
setChanged();
}
public void removeFromImplementedTypes(DMType aType) {
_implementedTypes.remove(aType);
aType.setOwner(null);
setChanged();
}
public DMType createNewImplementedType() throws DuplicateMethodSignatureException {
DMType newImplementedType = DMType.makeResolvedDMType(getDMModel().getDMEntity(Object.class));
addToImplementedTypes(newImplementedType);
return newImplementedType;
}
public void deleteImplementedType(DMType type) throws DuplicateMethodSignatureException {
removeFromImplementedTypes(type);
}
public boolean isImplementedTypeAddable(DMType type) {
return !getIsReadOnly();
}
public boolean isImplementedTypeDeletable(DMType type) {
return !getIsReadOnly();
}
// Used while serializing
public String _getSerializedImplementedTypes() {
if (getImplementedTypes().size() == 0) {
return null;
}
StringBuffer sb = new StringBuffer();
boolean isFirst = true;
for (DMType t : getImplementedTypes()) {
sb.append((isFirst ? "" : ",") + t.getStringRepresentation());
isFirst = false;
}
return sb.toString();
}
// Used while deserializing
public void _setSerializedImplementedTypes(String aString) {
if (logger.isLoggable(Level.FINE)) {
logger.fine("Trying to decode [" + aString + "]");
}
DMTypeTokenizer tt = new DMTypeTokenizer(aString);
while (tt.hasMoreTokens()) {
String next = tt.nextToken();
DMType type = getDMModel().getDmTypeConverter().convertFromString(next, this, getProject());
addToImplementedTypes(type);
if (logger.isLoggable(Level.FINE)) {
logger.fine("Decoded " + type.getStringRepresentation());
}
}
}
public Vector<DMTranstyper> getDeclaredTranstypers() {
return _declaredTranstypers;
}
public void setDeclaredTranstypers(Vector<DMTranstyper> declaredTranstypers) {
for (DMTranstyper tt : declaredTranstypers) {
addToDeclaredTranstypers(tt);
}
}
public void addToDeclaredTranstypers(DMTranstyper aTranstyper) {
aTranstyper.setDeclaringEntity(this);
_declaredTranstypers.add(aTranstyper);
orderedChildren = null;
if (getDMModel() != null) {
getDMModel().addToDeclaredTranstypers(aTranstyper);
}
setChanged();
notifyObservers(new TranstyperRegistered(aTranstyper));
}
public void removeFromDeclaredTranstypers(DMTranstyper aTranstyper) {
aTranstyper.setDeclaringEntity(null);
_declaredTranstypers.remove(aTranstyper);
orderedChildren = null;
if (getDMModel() != null) {
getDMModel().removeFromDeclaredTranstypers(aTranstyper);
}
setChanged();
notifyObservers(new TranstyperUnregistered(aTranstyper));
}
public DMTranstyper getDMTranstyper(String aTranstyperName) {
for (DMTranstyper tt : getDeclaredTranstypers()) {
if (tt.getName().equals(aTranstyperName)) {
return tt;
}
if (tt.getJavaMethodName().equals(aTranstyperName)) {
return tt;
}
}
return null;
}
private boolean mustBeImported(String className) {
if (className.indexOf(".") == -1) {
return false;
}
if (className.startsWith("default_package")) {
return false;
}
if (className.startsWith("java.lang")) {
return false;
}
return getPackage() == null || getPackage().isDefaultPackage()
|| !getPackage().getName().equals(className.substring(0, className.lastIndexOf('.')));
}
private void appendParameters(List<DMType> types, List<String> imports) {
if (types.size() == 0) {
return;
}
for (DMType t : types) {
appendToImports(t, imports);
appendParameters(t.getParameters(), imports);
}
}
private void appendToImports(DMType t, List<String> imports) {
if (t == null) {
return;
}
if (t.getBaseEntity() == null) {
if (logger.isLoggable(Level.SEVERE)) {
logger.severe("Cannot resolve type : " + t);
}
return;
}
if (t.getBaseEntity().getEntityClassName() == null) {
if (logger.isLoggable(Level.SEVERE)) {
logger.severe("No className for type : " + t);
}
return;
}
String candidate = t.getBaseEntity().getFullQualifiedName();
if (mustBeImported(candidate) && !imports.contains(candidate)) {
imports.add(candidate);
}
}
public List<String> getAllNeededImports() {
Vector<String> reply = new Vector<String>();
if (getParentType() != null) {
appendToImports(getParentType(), reply);
appendParameters(getParentType().getParameters(), reply);
}
for (DMProperty p : getProperties().values()) {
appendToImports(p.getType(), reply);
if (p.getType() != null) {
appendParameters(p.getType().getParameters(), reply);
}
}
for (DMMethod m : getMethods().values()) {
if (m.getReturnType() != null) {
appendToImports(m.getReturnType(), reply);
appendParameters(m.getReturnType().getParameters(), reply);
}
for (DMMethodParameter param : m.getParameters()) {
appendToImports(param.getType(), reply);
if (param.getType() != null) {
appendParameters(param.getType().getParameters(), reply);
}
}
}
return reply;
}
/**
* Tells if code generation is applicable for related DMEntity
*
* @return
*/
public boolean isCodeGenerationApplicable() {
return true;
}
public static class EntityInPackageCannotUseEntityOfTheDefaultPackage extends
ValidationRule<EntityInPackageCannotUseEntityOfTheDefaultPackage, DMEntity> {
public EntityInPackageCannotUseEntityOfTheDefaultPackage() {
super(DMEntity.class, "entity_in_package_cannot_use_entity_of_the_default_package");
}
private void addToVectorIfInDefaultPackage(DMType type, Vector<DMEntity> v) {
if (type == null) {
return;
}
if (type.getBaseEntity() == null) {
return;
}
if (type.getBaseEntity().isInDefaultPackage() && !v.contains(type.getBaseEntity())) {
v.add(type.getBaseEntity());
}
for (DMType t : type.getParameters()) {
addToVectorIfInDefaultPackage(t, v);
}
}
@Override
public ValidationIssue<EntityInPackageCannotUseEntityOfTheDefaultPackage, DMEntity> applyValidation(DMEntity entity) {
if (entity.isInDefaultPackage()) {
return null;
}
Vector<DMEntity> v = new Vector<DMEntity>();
addToVectorIfInDefaultPackage(entity.getParentType(), v);
for (DMProperty p : entity.getProperties().values()) {
addToVectorIfInDefaultPackage(p.getType(), v);
}
for (DMMethod m : entity.getMethods().values()) {
if (m.getReturnType() != null) {
addToVectorIfInDefaultPackage(m.getReturnType(), v);
}
for (DMMethodParameter param : m.getParameters()) {
addToVectorIfInDefaultPackage(param.getType(), v);
}
}
if (v.size() > 0) {
StringBuilder sb = new StringBuilder(
FlexoLocalization.localizedForKey("the_following_entities_are_in_the_default_package_and_cannot_be_used_by") + " "
+ entity.getFullQualifiedName()).append(": ");
for (DMEntity e : v) {
sb.append(e.getName()).append(" ");
}
ValidationError<EntityInPackageCannotUseEntityOfTheDefaultPackage, DMEntity> vr = new ValidationError<EntityInPackageCannotUseEntityOfTheDefaultPackage, DMEntity>(
this, entity, sb.toString());
vr.setLocalized(true);
return vr;
}
return null;
}
}
public DMPropertyImplementationType getPropertyDefaultImplementationType() {
return DMPropertyImplementationType.PUBLIC_ACCESSORS_PRIVATE_FIELD;
}
}