org.andromda.metafacades.emf.uml22.OperationFacadeLogicImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of andromda-metafacades-emf-uml22 Show documentation
Show all versions of andromda-metafacades-emf-uml22 Show documentation
The Eclipse EMF UML2 v2.X metafacades. This is the set of EMF UML2 2.X metafacades
implementations. These implement the common UML metafacades for .uml model files.
The newest version!
package org.andromda.metafacades.emf.uml22;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
import org.andromda.metafacades.uml.ClassifierFacade;
import org.andromda.metafacades.uml.ConstraintFacade;
import org.andromda.metafacades.uml.DependencyFacade;
import org.andromda.metafacades.uml.MetafacadeUtils;
import org.andromda.metafacades.uml.ModelElementFacade;
import org.andromda.metafacades.uml.NameMasker;
import org.andromda.metafacades.uml.OperationFacade;
import org.andromda.metafacades.uml.ParameterFacade;
import org.andromda.metafacades.uml.TypeMappings;
import org.andromda.metafacades.uml.UMLMetafacadeProperties;
import org.andromda.metafacades.uml.UMLProfile;
import org.andromda.translation.ocl.ExpressionKinds;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.collections.Transformer;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.eclipse.uml2.uml.CallConcurrencyKind;
import org.eclipse.uml2.uml.LiteralUnlimitedNatural;
import org.eclipse.uml2.uml.Operation;
import org.eclipse.uml2.uml.Parameter;
import org.eclipse.uml2.uml.ParameterDirectionKind;
import org.eclipse.uml2.uml.Type;
/**
* MetafacadeLogic implementation for
* org.andromda.metafacades.uml.OperationFacade.
*
* @see org.andromda.metafacades.uml.OperationFacade
* @author Bob Fields
*/
public class OperationFacadeLogicImpl
extends OperationFacadeLogic
{
private static final long serialVersionUID = 34L;
/**
* The logger instance.
*/
private static final Logger LOGGER = Logger.getLogger(OperationFacadeLogicImpl.class);
/**
* @param metaObject
* @param context
*/
public OperationFacadeLogicImpl(
final Operation metaObject,
final String context)
{
super(metaObject, context);
}
/**
* Not yet implemented, always returns null. To implement: walk through the
* related elements from the Sequence Diagram or OCL Body in the UML model to produce compilable code.
* @return null
* @see org.andromda.metafacades.uml.OperationFacade#getMethodBody()
*/
@Override
protected String handleGetMethodBody()
{
return null;
}
/**
* Overridden to provide name masking.
*
* @see org.andromda.metafacades.uml.ModelElementFacade#getName()
*/
@Override
protected String handleGetName()
{
final String nameMask = String.valueOf(this.getConfiguredProperty(UMLMetafacadeProperties.OPERATION_NAME_MASK));
return NameMasker.mask(
super.handleGetName(),
nameMask);
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#getSignature()
*/
@Override
protected String handleGetSignature()
{
return this.getSignature(true);
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#getCall()
*/
@Override
protected String handleGetCall()
{
return this.getCall(this.handleGetName());
}
/**
* Constructs the operation call with the given name
*
* @param name
* the name form which to construct the operation call.
* @return the operation call.
*/
private String getCall(final String name)
{
final StringBuilder buffer = new StringBuilder(name);
buffer.append('(');
buffer.append(this.getArgumentNames());
buffer.append(')');
return buffer.toString();
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#getTypedArgumentList()
*/
@Override
protected String handleGetTypedArgumentList()
{
return this.getTypedArgumentList(true);
}
private String getTypedArgumentList(final boolean withArgumentNames)
{
// TODO: Possible covariant of the method 'getTypedArgumentList' defined in the class 'OperationFacadeLogic'
return MetafacadeUtils.getTypedArgumentList(
this.getArguments(),
withArgumentNames,
null);
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#isStatic()
*/
@Override
protected boolean handleIsStatic()
{
return this.metaObject.isStatic();
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#isAbstract()
*/
@Override
protected boolean handleIsAbstract()
{
return this.metaObject.isAbstract();
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#getExceptionList()
*/
@Override
protected String handleGetExceptionList()
{
return this.getExceptionList(null);
}
/**
* Finds both exceptions and exception dependency references
* @see org.andromda.metafacades.uml.OperationFacade#getExceptions()
*/
@Override
protected Collection handleGetExceptions()
{
final Collection exceptions = new LinkedHashSet();
// finds both exceptions and exception references
final class ExceptionFilter
implements Predicate
{
public boolean evaluate(final Object object)
{
boolean hasException = object instanceof DependencyFacade;
if (hasException)
{
final DependencyFacade dependency = (DependencyFacade)object;
// first check for exception references
hasException = dependency.hasStereotype(UMLProfile.STEREOTYPE_EXCEPTION_REF);
// if there wasn't any exception reference
// now check for actual exceptions
if (!hasException)
{
final ModelElementFacade targetElement = dependency.getTargetElement();
hasException = targetElement != null && targetElement.hasStereotype(
UMLProfile.STEREOTYPE_EXCEPTION);
}
}
return hasException;
}
}
// first get any dependencies on this operation's
// owner (because these will represent the default exception(s))
final Collection ownerDependencies = new ArrayList(this.getOwner().getSourceDependencies());
if (!ownerDependencies.isEmpty())
{
CollectionUtils.filter(ownerDependencies, new ExceptionFilter());
exceptions.addAll(ownerDependencies);
}
final Collection operationDependencies = new ArrayList(this.getSourceDependencies());
// now get any exceptions directly on the operation
if (!operationDependencies.isEmpty())
{
CollectionUtils.filter(operationDependencies, new ExceptionFilter());
exceptions.addAll(operationDependencies);
}
// now transform the dependency(s) to the actual exception(s)
CollectionUtils.transform(exceptions, new Transformer()
{
public Object transform(final Object object)
{
if (object == null) return null;
return ((DependencyFacade)object).getTargetElement();
}
});
// finally add in any members of the UML2 RaisedException list
// (the 'proper' UML2 way of doing exceptions .. or at least one way).
final Collection raisedExceptions = this.metaObject.getRaisedExceptions();
exceptions.addAll(this.shieldedElements(raisedExceptions));
return exceptions;
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#isReturnTypePresent()
*/
@Override
protected boolean handleIsReturnTypePresent()
{
boolean hasReturnType = false;
if (this.getReturnType() != null)
{
hasReturnType = !("void".equalsIgnoreCase(StringUtils.trimToEmpty(this.getReturnType().getFullyQualifiedName()))
|| StringUtils.trimToEmpty(this.getReturnType().getFullyQualifiedName(true)).equals(UMLProfile.VOID_TYPE_NAME));
}
if (LOGGER.isDebugEnabled())
{
final String rtnFQN = this.getReturnType().getFullyQualifiedName(true);
final boolean voidType = "void".equalsIgnoreCase(StringUtils.trimToEmpty(this.getReturnType().getFullyQualifiedName()));
final String voidRtn = this.getReturnType().getFullyQualifiedName();
LOGGER.debug("OperationFacadeLogicImpl.handleIsReturnTypePresent rtnFQN=" + rtnFQN + " voidType=" + voidType + " voidRtn=" + voidRtn + " hasReturnType=" + hasReturnType);
}
return hasReturnType;
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#isExceptionsPresent()
*/
@Override
protected boolean handleIsExceptionsPresent()
{
return !this.getExceptions().isEmpty();
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#getArgumentNames()
*/
@Override
protected String handleGetArgumentNames()
{
final StringBuilder buffer = new StringBuilder();
final Iterator iterator = this.metaObject.getOwnedParameters().iterator();
boolean commaNeeded = false;
final String comma = ", ";
while (iterator.hasNext())
{
final Parameter parameter = iterator.next();
if (!parameter.getDirection().equals(ParameterDirectionKind.RETURN_LITERAL))
{
if (commaNeeded)
{
buffer.append(comma);
}
final ParameterFacade facade = (ParameterFacade)this.shieldedElement(parameter);
buffer.append(facade.getName());
commaNeeded = true;
}
}
return buffer.toString();
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#getArgumentTypeNames()
*/
@Override
protected String handleGetArgumentTypeNames()
{
final StringBuilder buffer = new StringBuilder();
final Iterator iterator = this.metaObject.getOwnedParameters().iterator();
boolean commaNeeded = false;
while (iterator.hasNext())
{
final Parameter parameter = iterator.next();
if (!parameter.getDirection().equals(ParameterDirectionKind.RETURN_LITERAL))
{
if (commaNeeded)
{
buffer.append(", ");
}
final ParameterFacade facade = (ParameterFacade)this.shieldedElement(parameter);
buffer.append(facade.getType().getFullyQualifiedName());
commaNeeded = true;
}
}
return buffer.toString();
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#isQuery()
*/
@Override
protected boolean handleIsQuery()
{
return this.metaObject.isQuery();
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#getConcurrency()
*/
@Override
protected String handleGetConcurrency()
{
String concurrency = null;
final CallConcurrencyKind concurrencyKind = this.metaObject.getConcurrency();
if (concurrencyKind == null || concurrencyKind.equals(CallConcurrencyKind.CONCURRENT_LITERAL))
{
concurrency = "concurrent";
}
else if (concurrencyKind.equals(CallConcurrencyKind.GUARDED_LITERAL))
{
concurrency = "guarded";
}
else// CallConcurrencyKindEnum.CCK_SEQUENTIAL
{
concurrency = "sequential";
}
final TypeMappings languageMappings = this.getLanguageMappings();
if (languageMappings != null)
{
concurrency = languageMappings.getTo(concurrency);
}
return concurrency;
}
/**
* Gets the pattern for constructing the precondition name.
*
* @return the precondition pattern.
*/
private String getPreconditionPattern()
{
return String.valueOf(this.getConfiguredProperty(UMLMetafacadeProperties.PRECONDITION_NAME_PATTERN));
}
/**
* Gets the pattern for constructing the postcondition name.
*
* @return the postcondition pattern.
*/
private String getPostconditionPattern()
{
return String.valueOf(this.getConfiguredProperty(UMLMetafacadeProperties.POSTCONDITION_NAME_PATTERN));
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#getPreconditionName()
*/
@Override
protected String handleGetPreconditionName()
{
return this.getPreconditionPattern().replaceAll(
"\\{0\\}",
this.handleGetName());
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#getPostconditionName()
*/
@Override
protected String handleGetPostconditionName()
{
return this.getPostconditionPattern().replaceAll(
"\\{0\\}",
this.handleGetName());
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#getPreconditionSignature()
*/
@Override
protected String handleGetPreconditionSignature()
{
return MetafacadeUtils.getSignature(
this.getPreconditionName(),
this.getArguments(),
true,
null);
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#getPreconditionCall()
*/
@Override
protected String handleGetPreconditionCall()
{
return this.getCall(this.getPreconditionName());
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#isPreconditionsPresent()
*/
@Override
protected boolean handleIsPreconditionsPresent()
{
final Collection preconditions = this.getPreconditions();
return preconditions != null && !preconditions.isEmpty();
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#isPostconditionsPresent()
*/
@Override
protected boolean handleIsPostconditionsPresent()
{
final Collection postconditions = this.getPostconditions();
return postconditions != null && !postconditions.isEmpty();
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#findTaggedValue(String,
* boolean)
*/
@Override
protected Object handleFindTaggedValue(
final String name,
final boolean follow)
{
final String trimName = StringUtils.trimToEmpty(name);
Object value = this.findTaggedValue(trimName);
if (follow)
{
ClassifierFacade type = this.getReturnType();
while (value == null && type != null)
{
value = type.findTaggedValue(trimName);
type = (ClassifierFacade)type.getGeneralization();
}
}
return value;
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#getExceptionList(String)
*/
@Override
protected String handleGetExceptionList(String initialExceptions)
{
initialExceptions = StringUtils.trimToEmpty(initialExceptions);
final StringBuilder exceptionList = new StringBuilder(initialExceptions);
// TODO getExceptions = Collection or ?
final Collection exceptions = this.getExceptions();
if (exceptions != null && !exceptions.isEmpty())
{
if (StringUtils.isNotBlank(initialExceptions))
{
exceptionList.append(", ");
}
final Iterator exceptionIt = exceptions.iterator();
while (exceptionIt.hasNext())
{
final ModelElementFacade exception = (ModelElementFacade)exceptionIt.next();
exceptionList.append(exception.getFullyQualifiedName());
if (exceptionIt.hasNext())
{
exceptionList.append(", ");
}
}
}
return exceptionList.toString();
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#getSignature(boolean)
*/
@Override
protected String handleGetSignature(final boolean withArgumentNames)
{
return MetafacadeUtils.getSignature(
this.handleGetName(),
this.getArguments(),
withArgumentNames,
null);
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#getTypedArgumentList(String)
*/
@Override
protected String handleGetTypedArgumentList(final String modifier)
{
return MetafacadeUtils.getTypedArgumentList(
this.getArguments(),
true,
modifier);
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#getSignature(String)
*/
@Override
protected String handleGetSignature(final String argumentModifier)
{
return MetafacadeUtils.getSignature(
this.handleGetName(),
this.getArguments(),
true,
argumentModifier);
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#getOwner()
*/
@Override
protected Object handleGetOwner()
{
Object obj = null;
// Fix from UML2, no longer calls getOwner to get the owning Class
if (this.metaObject.getInterface()!=null)
{
obj = this.metaObject.getInterface();
}
else if (this.metaObject.getDatatype()!=null)
{
obj = this.metaObject.getDatatype();
}
else
{
obj = this.metaObject.getClass_();
}
return obj;
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#getParameters()
*/
@Override
protected Collection handleGetParameters()
{
final Collection params = new ArrayList(this.metaObject.getOwnedParameters());
params.add(this.metaObject.getReturnResult());
CollectionUtils.filter(
params,
new Predicate()
{
public boolean evaluate(final Object object)
{
return object != null && !((Parameter)object).isException();
}
});
return params;
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#getReturnType()
*/
@Override
protected Type handleGetReturnType()
{
return this.metaObject.getType();
}
/**
* @return this.getReturnType().getFullyQualifiedName()
* @see org.andromda.metafacades.uml.OperationFacade#getGetterSetterReturnTypeName()
*/
protected String handleGetGetterSetterReturnTypeName()
{
String name = null;
final ClassifierFacade returnType = this.getReturnType();
if (returnType!=null && (this.getUpper() > 1 || this.getUpper() == LiteralUnlimitedNatural.UNLIMITED))
{
final TypeMappings mappings = this.getLanguageMappings();
name =
this.handleIsOrdered() ? mappings.getTo(UMLProfile.LIST_TYPE_NAME)
: mappings.getTo(UMLProfile.COLLECTION_TYPE_NAME);
// set this attribute's type as a template parameter if required
if (BooleanUtils.toBoolean(
ObjectUtils.toString(this.getConfiguredProperty(UMLMetafacadeProperties.ENABLE_TEMPLATING))))
{
String type = returnType.getFullyQualifiedName();
if (returnType.isPrimitive())
{
// Can't template primitive values, Objects only. Convert to wrapped.
type = this.getReturnType().getWrapperName();
}
// Allow List implementations.
/*// Don't apply templating to modeled array types
if (returnType.isArrayType())
{
type = type.substring(0, type.length()-2);
}*/
name += '<' + type + '>';
}
}
if (name == null && returnType != null)
{
name = returnType.getFullyQualifiedName();
// Special case: lower bound overrides primitive/wrapped type declaration
// TODO Apply to all primitive types, not just booleans. This is a special case because of is/get Getters.
if (this.getReturnType().isBooleanType())
{
if (this.getReturnType().isPrimitive() && (this.getLower() < 1))
{
// Type is optional, should not be primitive
name = StringUtils.capitalize(name);
}
else if (!this.getReturnType().isPrimitive() && this.getLower() > 0)
{
// Type is required, should not be wrapped
name = StringUtils.uncapitalize(name);
}
}
}
return name;
}
/**
* @return this.metaObject.isOrdered()
* @see org.andromda.metafacades.uml.OperationFacade#isOrdered()
*/
protected boolean handleIsOrdered()
{
return this.metaObject.isOrdered();
}
/**
* @return this.getUpper() > 1 || this.getUpper() == LiteralUnlimitedNatural.UNLIMITED
* @see org.andromda.metafacades.uml.OperationFacade#isMany()
*/
protected boolean handleIsMany()
{
// Because of MD11.5 (their multiplicity are String), we cannot use
// isMultiValued()
// RJF3 True if either the operation is many or the return parameter is many
final ParameterFacade returnParameter = this.getReturnParameter();
// Parameter or parameter type may be null during model validation
final boolean returnMany = returnParameter!=null && returnParameter.getType()!=null &&
(returnParameter.getUpper() > 1 ||
returnParameter.getUpper() == LiteralUnlimitedNatural.UNLIMITED
|| returnParameter.getType().isArrayType());
return returnMany || this.getUpper() > 1 || this.getUpper() == LiteralUnlimitedNatural.UNLIMITED;
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#getArguments()
*/
@Override
protected Collection handleGetArguments()
{
final Collection arguments = new ArrayList(this.metaObject.getOwnedParameters());
CollectionUtils.filter(
arguments,
new Predicate()
{
public boolean evaluate(final Object object)
{
final Parameter param = (Parameter)object;
return !param.getDirection().equals(ParameterDirectionKind.RETURN_LITERAL) && !param.isException();
}
});
return arguments;
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#getPreconditions()
*/
@Override
protected Collection handleGetPreconditions()
{
return this.handleGetConstraints(ExpressionKinds.PRE);
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#getPostconditions()
*/
@Override
protected Collection handleGetPostconditions()
{
return this.handleGetConstraints(ExpressionKinds.POST);
}
/**
* @see org.andromda.core.metafacade.MetafacadeBase#getValidationOwner()
*/
@Override
public Object getValidationOwner()
{
return this.getOwner();
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#findParameter(String)
*/
@Override
protected ParameterFacade handleFindParameter(final String name)
{
return (ParameterFacade)this.shieldedElement(this.metaObject.getOwnedParameter(name, null));
}
/**
* Get the UML upper multiplicity Not implemented for UML1.4
* @return multiplicity upperBound
*/
@Override
protected int handleGetUpper()
{
// MD11.5 Exports multiplicity as String
return this.metaObject.getUpper();
//return UmlUtilities.parseMultiplicity(this.metaObject.getUpper(), 1);
}
/**
* Get the UML lower multiplicity Not implemented for UML1.4
* @return multiplicity lowerBound
*/
@Override
protected int handleGetLower()
{
// MD11.5 Exports multiplicity as String
return this.metaObject.getLower();
//return UmlUtilities.parseLowerMultiplicity(this.metaObject.getLower(),
// (ClassifierFacade) this.getReturnType(), "0");
// ObjectUtils.toString(this.getConfiguredProperty(UMLMetafacadeProperties.DEFAULT_MULTIPLICITY)));
}
/**
* Get the first UML2 ReturnResult parameter. Not implemented for UML1.4
* @return ReturnResult parameter
*/
@Override
public ParameterFacade handleGetReturnParameter()
{
return (ParameterFacade)this.shieldedElement(this.metaObject.getReturnResult());
}
/**
* Override to change private to public, since it makes no sense to have private operations in generated code
* Allows for protected, package level visibility of operations in the model
* @return String visibility
*/
@Override
protected String handleGetVisibility()
{
String visibility = super.handleGetVisibility();
if (visibility==null || visibility.equals("private"))
{
visibility = "public";
}
return visibility;
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#isOverriding()
*/
@Override
protected boolean handleIsOverriding()
{
return this.getOverriddenOperation() != null;
}
/**
* @see org.andromda.metafacades.uml.OperationFacade#getOverriddenOperation()
*/
@Override
protected OperationFacade handleGetOverriddenOperation()
{
OperationFacade overriddenOperation = null;
final String signature = this.getSignature(false);
ClassifierFacade ancestor = this.getOwner().getSuperClass();
while (overriddenOperation == null && ancestor != null)
{
for (final Iterator operationIterator = ancestor.getOperations().iterator();
overriddenOperation == null && operationIterator.hasNext();)
{
final OperationFacade ancestorOperation = operationIterator.next();
if (signature.equals(ancestorOperation.getSignature(false)))
{
overriddenOperation = ancestorOperation;
}
}
ancestor = ancestor.getSuperClass();
}
return overriddenOperation;
}
/**
* @return this.metaObject.isLeaf()
* @see org.andromda.metafacades.uml.OperationFacade#isLeaf()
*/
protected boolean handleIsLeaf()
{
return this.metaObject.isLeaf();
}
/**
* @return this.metaObject.isUnique()
* @see org.andromda.metafacades.uml.OperationFacade#isUnique()
*/
protected boolean handleIsUnique()
{
return this.metaObject.isUnique();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy