ModelElement.java
package org.andromda.core.cartridge.template;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import org.andromda.core.common.ClassUtils;
import org.andromda.core.common.ExceptionUtils;
import org.andromda.core.common.Introspector;
import org.andromda.core.metafacade.MetafacadeBase;
import org.andromda.core.profile.Profile;
import org.apache.commons.lang.StringUtils;
/**
* Represents a single template <modelElement/> nested within the <modelElements/> element. It stores the
* actual metafacade instances which match the model element criteria (i.e. stereotype, type, etc) defined by this
* instance.
*
* @author Chad Brandon
* @author Bob Fields
* @see ModelElements
*/
public class ModelElement
{
private String stereotype;
/**
* Gets the stereotype of this modelElement.
*
* @return Returns the stereotype.
*/
public String getStereotype()
{
return Profile.instance().get(this.stereotype);
}
/**
* Returns <code>true</code> or <code>false</code> depending on whether or not this model element has a stereotype
* defined.
*
* @return true/false
*/
public boolean hasStereotype()
{
return this.stereotype != null;
}
/**
* Stores the types defined for this model element.
*/
private final Collection<Type> types = new ArrayList<Type>();
/**
* Gets all types associated with this model element.
*
* @return the collection of types.
*/
public Collection<Type> getTypes()
{
return this.types;
}
/**
* Returns <code>true</code> or <code>false</code> depending on whether or not this model element has any type
* elements defined.
*
* @return true/false
*/
public boolean hasTypes()
{
return !this.getTypes().isEmpty();
}
/**
* Sets the stereotype of the ModelElement.
*
* @param stereotype The stereotype to set.
*/
public void setStereotype(final String stereotype)
{
this.stereotype = stereotype;
ExceptionUtils.checkEmpty("stereotype", this.stereotype);
}
/**
* Adds the <code>type</code> to the collection of types belonging to this model element.
*
* @param type the {@link Type}instance.
*/
public void addType(final Type type)
{
ExceptionUtils.checkNull("type", type);
this.types.add(type);
}
/**
* Stores the name of the variable for this model element.
*/
private String variable;
/**
* Gets the variable stereotype of this modelElement (this is what is made available to a template during
* processing).
*
* @return Returns the variable.
*/
public String getVariable()
{
return this.variable;
}
/**
* Sets the variable name.
*
* @param variable The variable to set.
*/
public void setVariable(final String variable)
{
this.variable = StringUtils.trimToEmpty(variable);
}
/**
* The metafacades for this model element.
*/
private Collection<MetafacadeBase> metafacades = new ArrayList<MetafacadeBase>();
/**
* Sets the current metafacades that belong to this ModelElement instance.
*
* @param metafacades the collection of metafacades
*/
public void setMetafacades(final Collection<MetafacadeBase> metafacades)
{
ExceptionUtils.checkNull("metafacades", metafacades);
this.metafacades = metafacades;
this.applyTypeFiltering();
}
/**
* Gets the metafacades that belong to this ModelElement instance. These are the actual elements from the model.
*
* @return the collection of metafacades.
*/
public Collection<MetafacadeBase> getMetafacades()
{
return this.metafacades;
}
/**
* Applies any filtering by any types specified within this model element.
*/
private void applyTypeFiltering()
{
if (this.hasTypes())
{
for (final Iterator iterator = this.metafacades.iterator(); iterator.hasNext();)
{
if (!accept(iterator.next()))
{
iterator.remove();
}
}
}
}
/**
* Checks the <code>object</code> to see whether or not its acceptable. It matches on the types and each type's
* properties. <strong>NOTE:</strong> protected visibility to improve performance from within {@link
* #applyTypeFiltering()}
*
* @param metafacade the metafacade to check
* @return true/false
*/
private boolean accept(final Object metafacade)
{
boolean accept = true;
for (Type type : this.types)
{
if (StringUtils.isNotBlank(type.getName()))
{
try
{
accept = ClassUtils.loadClass(type.getName()).isAssignableFrom(metafacade.getClass());
// if the type matches the name, continue
if (accept)
{
for (Type.Property property : type.getProperties())
{
accept =
Introspector.instance().containsValidProperty(
metafacade,
property.getName(),
property.getValue());
if (!accept)
{
// break out of the loop on the first invalid
// property since all properties should be valid.
break;
}
}
}
}
catch (final Throwable throwable)
{
accept = false;
}
}
}
return accept;
}
}