This repository has been archived on 2024-04-22. You can view files and clone it, but cannot push or open issues or pull requests.
SecureUML-GUI/src/ch/ethz/infsec/secureumlgui/modelmapping/GenericDialectHelper.java

1830 lines
58 KiB
Java

/**
*
*/
package ch.ethz.infsec.secureumlgui.modelmapping;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.Set;
import javax.jmi.reflect.RefObject;
import org.apache.log4j.Logger;
import org.argouml.model.Model;
import org.omg.uml.foundation.core.AssociationClass;
import org.omg.uml.foundation.core.Classifier;
import org.omg.uml.foundation.core.ModelElement;
import org.omg.uml.foundation.core.Namespace;
import org.omg.uml.foundation.core.Stereotype;
import org.omg.uml.foundation.core.UmlClass;
import ch.ethz.infsec.secureumlgui.Util;
import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.ActionType;
import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.AssociationEnd;
import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.DialectMetaModelInfo;
import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.InterResourceAssociation;
import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.MetaModelClass;
import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.MetaModelConst;
import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.ResourceType;
import ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions.OclEvaluatorException;
import ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions.OclExpression;
import ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions.OclExpressionEvaluator;
import ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions.OclExpressionsParser;
import ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions.OclUmlExpressionEvaluator;
import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger;
import ch.ethz.infsec.secureumlgui.main.SecureUmlConstants;
import ch.ethz.infsec.secureumlgui.transformation.MetaModelMap;
import ch.ethz.infsec.secureumlgui.transformation.ModelMap;
import ch.ethz.infsec.secureumlgui.wrapper.ActionWrapper;
/**
*
*/
public class GenericDialectHelper
{
/**
*
*/
// public GenericDialectHelper(DialectMetaModelInfo mmInfo)//, MetaModelMap map)
// {
// this.dialectMetaModelInfo = mmInfo;
//
// this.map = MetaModelMap.getDefault();
// }
/**
*
*/
private GenericDialectHelper()
{
this.map = MetaModelMap.getDefault();
logger.disableLoggerContext(logger.MODELMAPPER_DETAILLED);
}
static private GenericDialectHelper instance;
static public GenericDialectHelper getInstance()
{
if (instance == null)
instance = new GenericDialectHelper();
return instance;
}
DialectMetaModelInfo dialectMetaModelInfo;
MetaModelMap map;
MultiContextLogger logger = MultiContextLogger.getDefault();
private static Logger aLog = Logger.getLogger(GenericDialectHelper.class);
public MetaModelClass getMetaModelClass(ModelElement m)
{
if (m == null || dialectMetaModelInfo == null) {
aLog.debug("getMetaModelClass: ModelElement or dialectMetaModelInfo == null (" + m + ")");
return null;
}
Collection<MetaModelClass> mmcs = dialectMetaModelInfo
.getMetaModelClasses();
for (MetaModelClass mmc : mmcs)
{
String umlClassNameTag = mmc.getUmlClassName();
if (hasType(m, umlClassNameTag))
{
return mmc;
}
}
// if mmc not found until here
return getResourceType(m);
}
/** If the UML Modelelement m represents a SecureUML element
* (Role, Permission, Policy or Resource), this function returns it's
* Resourcetype.
*
* For roles and permissions, dummy resourcetypes
* are created.
*/
public ResourceType getSecureUmlType(ModelElement m)
{
if(isSecureUmlRole(m)) {
return SecureUmlConstants.getRoleResourceTypeDummy();
}
else if(isSecureUmlPermission(m)) {
return SecureUmlConstants.getPermissionResourceTypeDummy();
}
else if(isSecureUmlPolicy(m)) {
return SecureUmlConstants.getPolicyResourceTypeDummy();
}
else { // is the target a resource?
return getResourceType(m);
}
}
/**
* If the UML ModelElement m represents a SecureUML-Resource, this function
* examines and returns it's ResourceType - otherwise returns null.
*
* @param m
* UML ModelElement
* @return The ResourceType of m if exists, null otherwise
*/
public ResourceType getResourceType(ModelElement m) {
if (m == null || dialectMetaModelInfo == null)
return null;
for (ResourceType resourceType : dialectMetaModelInfo.getResourceTypes() ) {
// Assume m is of Resource-Type r
logger.info(MultiContextLogger.MODELMAPPER_DETAILLED, "is "
+ m.getName() + " a " + resourceType.getName() + "?");
if (!hasType(m, resourceType.getUmlClassName())) {
logger.info(MultiContextLogger.MODELMAPPER_DETAILLED,
"no! (wrong class: " + m.getClass().getSimpleName());
continue;
}
// if anchorPath == 'self'
String anchorPath = resourceType.getAnchorPath();
String modelElementStereotype = resourceType.getModelElementStereotype();
if (hasStereotype(m, modelElementStereotype)) {
resourcePath = m.getName();
logger.info(MultiContextLogger.MODELMAPPER_DETAILLED,
"ModelElement " + m.getName() + " is of ResourceType "
+ resourceType.getName());
logger.info(MultiContextLogger.MODELMAPPER_DETAILLED,
"... yes, marked explicitly!");
// found the right resource Type
return resourceType;
} else if (modelElementStereotype == null
|| modelElementStereotype.length() == 0) {
ModelElement anchor = findAnchor(m, resourceType);
ResourceType anchorType = getResourceType(anchor);
if (anchor != null
&& anchorType != null
&& hasStereotype(anchor, anchorType
.getModelElementStereotype())) {
String anchorName = Util.getProperty(anchor, "name")
.toString();
// logger.info("ModelElement "
// + m.getName()
// + " is of ResourceType "
// + r.getName());
// found the right Resource Type
logger.info(MultiContextLogger.MODELMAPPER_DETAILLED,
"... yes, implicitly " + "- because the anchor '"
+ anchorName + "' is a resource!");
return resourceType;
}
}
}
// else
// - if arrived here,
// the ModelElement m is not a ResourceType
// Collection<MetaModelClass> mmClasses =
// dialectMetaModelInfo.getMetaModelClasses();
// for (Iterator iter = mmClasses.iterator(); iter.hasNext();)
// {
// MetaModelClass mmClass = (MetaModelClass) iter.next();
// logger.info(MultiContextLogger.MODELMAPPER_DETAILLED, "is "
// + m.getName() + " a " + mmClass.getName() + "?");
// if (hasType(m, mmClass.getUmlClassName()))
// {
// logger.info(MultiContextLogger.MODELMAPPER_DETAILLED,
// "ModelElement " + m.getName()
// + " is of MetamodelClass " + mmClass.getName());
// }
// }
logger.info(MultiContextLogger.MODELMAPPER_DETAILLED, "... no!");
return null;
}
public ActionType getActionType(Object suAction)
{
if (suAction == null || dialectMetaModelInfo == null)
return null;
for (ActionType at : dialectMetaModelInfo.getActionTypes() )
{
// logger.info(MultiContextLogger.MODELMAPPER_DETAILLED, "is "
// + suAction + " actionType " + at.getName() + "?");
ActionWrapper suActionWrapper = ActionWrapper.createActionWrapper(suAction);
if(at.getShortName().equals(suActionWrapper.getName()))
{
// logger.info("...yes");
return at;
}
else
{
// logger.info("...no");
}
}
return null;
}
public boolean isSecureUmlRole(ModelElement m)
{
try
{
String umlClassName =
SecureUmlConstants.getRoleResourceTypeDummy().getUmlClassName();
String modelElementStereotype =
SecureUmlConstants.getRoleResourceTypeDummy().getModelElementStereotype();
// logger.info(
// "isSecureUmlRole("
// //+ m.get
// + umlClassName
// + " ?= "
// + m.getClass().getSimpleName()
// + ", "
// + modelElementStereotype
// + " ?= "
// + ((Stereotype) m.getStereotype().iterator().next()).getName());
if (hasType(m, umlClassName)
&& hasStereotype(m, modelElementStereotype))
{
return true;
}
}
catch (Exception e)
{
}
return false;
}
public boolean isSecureUmlPermission(ModelElement m)
{
// logger.info(
// "isSecureUmlPermission(umlClassname: "
// + umlClassName
// + ", stereotype: "
// + modelElementStereotype);
if (hasType(m, SecureUmlConstants.PERMISSION_CLASSNAME)
&& hasStereotype(m, SecureUmlConstants.STEREOTYPE_SECUML_PERMISSION))
{
return true;
}
else
return false;
}
public boolean isSecureUmlPolicy(ModelElement m) {
try
{
// logger.info(
// "isSecureUmlRole("
// //+ m.get
// + umlClassName
// + " ?= "
// + m.getClass().getSimpleName()
// + ", "
// + modelElementStereotype
// + " ?= "
// + ((Stereotype) m.getStereotype().iterator().next()).getName());
if (hasType(m, SecureUmlConstants.POLICY_CLASSNAME)
&& hasStereotype(m, SecureUmlConstants.STEREOTYPE_SECUML_POLICY))
{
return true;
}
}
catch (Exception e)
{
e.printStackTrace();
}
return false;
}
public boolean isSecureUmlExcpLevel(ModelElement m)
{
String umlClassName = "";
if (hasType(m, umlClassName) && hasStereotype(m, SecureUmlConstants.STEREOTYPE_SECUML_POLICY)) {
return true;
} else {
return false;
}
}
public Classifier findAnchor(AssociationClass permission)
{
Collection ends = permission.getConnection();
for (Iterator iter = ends.iterator(); iter.hasNext();)
{
org.omg.uml.foundation.core.AssociationEnd end =
(org.omg.uml.foundation.core.AssociationEnd) iter.next();
ResourceType rt = getResourceType(end.getParticipant());
if(rt != null)
return end.getParticipant();
}
return null;
}
public Classifier getPermissionRole(AssociationClass permission)
{
Collection ends = permission.getConnection();
for (Iterator iter = ends.iterator(); iter.hasNext();)
{
org.omg.uml.foundation.core.AssociationEnd end =
(org.omg.uml.foundation.core.AssociationEnd) iter.next();
boolean isRole = isSecureUmlRole(end.getParticipant());
if(isRole)
return end.getParticipant();
}
return null;
}
public UmlClass findAnchor(ModelElement resource)
{
logger.info("find Anchor for resource "+resource.getName());
ResourceType startPointResourceType =
getResourceType(resource);
return findAnchor(resource, startPointResourceType);
}
String resourcePath = null;
/** finds the Anchor of a Resource and calculates
* the Resource's resourcePath.
*
* @param resource
* @param startPointResourceType
* @return the anchor of the resource
*/
public UmlClass findAnchor(ModelElement resource,
ResourceType startPointResourceType)
{
// org.omg.uml.foundation.core.AssociationEnd end;
// end.
if (resource == null || startPointResourceType == null)
{
resourcePath = "";
return null;
}
resourcePath = resource.getName();
ResourceType resourceType = startPointResourceType;
ModelElement modelElement = resource;
// TODO: follow startPointResourceType.getAnchorPath()
// from startPoint
String anchorPath = startPointResourceType.getAnchorPath();
ModelElement result =
//evaluateUniquePathExpression(
evaluateUniqueOclExpression(
resource, resourceType, anchorPath);
if (result instanceof UmlClass)
return (UmlClass) result;
else
return null;
}
private ModelElement evaluateUniqueOclExpression(
ModelElement startpoint,
MetaModelClass metaModelClass,
/*ModelElement modelElement,*/
String oclExpression)
{
//Object startpoint = map.getElement(modelElement);
logger.info("parsing OCL-Expression: "
+ oclExpression);
OclExpressionsParser parser =
new OclExpressionsParser();
OclExpression expression =
parser.parseOclExpression(oclExpression);
// logger.info("OCL-Expression parsed - starting at "
// + startpoint.getClass().getSimpleName() + " "
// + startpoint.getName()
// + " with evaluation of: "
// + expression);
OclUmlExpressionEvaluator evaluator =
new OclUmlExpressionEvaluator(
expression, startpoint, startpoint,
dialectMetaModelInfo, metaModelClass);
try
{
Set result = evaluator.evaluateExpression();
this.resourcePath = evaluator.getResourcePath();
if(result == null || result.size() == 0)
{
logger.error("result set is empty");
logger.error("no anchor found for: " + startpoint.getName());
return null;
}
if(result.size() == 1)
{
Object o = result.iterator().next();
if (o instanceof ModelElement)
{
ModelElement me = (ModelElement) o;
// logger.info("anchor of "
// + startpoint.getName()
// + " is: "
// + me.getName());
return me;
}
}
else
{
logger.error("more than one Object in result set");
logger.error("no anchor found for: " + startpoint.getName());
}
}
catch (Exception e)
{
logger.logException(e);
}
return null;
}
public static final char OPENING_BRACKET_CHAR = '[';
public static final char CLOSING_BRACKET_CHAR = ']';
/**
* not working correctly,
* and using pathExpressions instead of OCL-Expressions
*
* @param startPoint
* @param metaModelClass
* @param maxdepth
* @param pathExpression
*
*/
private ModelElement evaluateUniquePathExpression(ModelElement startPoint, MetaModelClass metaModelClass, /*ModelElement modelElement,*/ String pathExpression, int maxdepth)
{
if(maxdepth < 0)
{
logger.error("evaluateUniquePathExpression recursion too deep");
return null;
}
maxdepth--;
ModelElement modelElement = startPoint;
String[] pathSteps = null;
if (pathExpression != null)
{
pathSteps = pathExpression.split("\\.");
}
// logger.info("evaluating path expression: " + pathExpression);
//ModelElement anchor;
if (pathSteps != null && pathExpression.length() > 0)
{
int startIndex = 0;
if(pathSteps[0].equals(MetaModelConst.SELF_PATH))
startIndex = 1;
int bracketsdepth = 0;
for (int i = startIndex; i < pathSteps.length; i++)
{
String step = pathSteps[i];
logger.info("evaluatePathExpression - step: " + step );
// boolean stepTaken = false;
Collection associations = dialectMetaModelInfo
.getInterResourceAssociations(metaModelClass);
for (Iterator iter = associations.iterator(); iter.hasNext();)
{
InterResourceAssociation association = (InterResourceAssociation) iter
.next();
ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.
AssociationEnd otherEnd =
association.getOtherEnd(metaModelClass);
//logger.info("evaluatePathExpression - otherEnd: " + otherEnd);
if(step.charAt(step.length()-1)
== CLOSING_BRACKET_CHAR)
// step is a selection
{
bracketsdepth = 0;
try
{
String condition =
step.substring(0, step.length()
-1);
// remove CLOSING_BRACKET_CHAR
if(condition.charAt(0)==OPENING_BRACKET_CHAR)
condition = condition.substring(1);
logger.info(
"evaluatePathExpression: " +
"evaluating selection with condition"
+ condition);
Collection c = null;
c = navigateAssociation(modelElement, otherEnd);
String leftpart = "";
String rightpart = "";
boolean equality = false;
if(condition.contains("="))
{
leftpart = condition.split("=")[0];
rightpart = condition.split("=")[1];
equality = true;
}
else if(condition.contains("<>"))
{
leftpart = condition.split("<>")[0];
rightpart = condition.split("<>")[1];
equality = false;
}
else
{
logger.error("evaluatePathExpression: invalid path selection condition");
return null;
}
for (Iterator iterator = c.iterator(); iterator.hasNext();)
{
ModelElement me = (ModelElement) iterator.next();
ModelElement leftModelElement = null;
if(leftpart.startsWith(MetaModelConst.SELF_PATH))
{
// logger.info(
// "would evaluate left part recursively, here: "
// + rightpart);
evaluateUniquePathExpression(
startPoint,
getResourceType(startPoint),
leftpart, maxdepth);
}
else
{
// logger.info(
// "would evaluate left part recursively, here: "
// + leftpart);
evaluateUniquePathExpression(
me,
getResourceType(me),
leftpart, maxdepth);
}
ModelElement rightModelElement = null;
if(rightpart.startsWith(MetaModelConst.SELF_PATH))
{
// logger.info(
// "would evaluate right part recursively, here: "
// + rightpart);
evaluateUniquePathExpression(
startPoint,
getResourceType(startPoint),
rightpart, maxdepth);
}
else
{
// logger.info(
// "would evaluate right part recursively, here: "
// + rightpart);
evaluateUniquePathExpression(
me,
getResourceType(me),
rightpart, maxdepth);
}
logger.info("Condition compares "
+ leftModelElement
+ " and "
+ rightModelElement);
boolean equals =
leftModelElement.equals(rightModelElement);
if(equals == equality)
{
modelElement = me;
// continue
}
//return me;
}
if(modelElement == null)
{
logger.error("there is no ModelElement " +
"satisfying the selection condition");
return null;
}
}
catch (Exception e)
{
logger.logException(e);
}
}
else if(step.indexOf(OPENING_BRACKET_CHAR) != -1
|| bracketsdepth > 0)
// step is first part of a selection
{
bracketsdepth = 1;
pathSteps[i+1] = step + pathSteps[i+1];
break;
}
else if (step.endsWith("*"))
// step is a repetition
{
step = step.substring(0, step.length() - 1);
if(otherEnd != null
&& otherEnd.getName().equals(
step.substring(0, step.length() - 1)))
{
//Collection c = navigateAssociation(modelElement, otherEnd);
ModelElement temp = null;
do // take this step 0-n times, as long as it leads somewhere else
{
temp =
takeAnchorPathStep(modelElement, step, otherEnd);
if(temp != null && temp != modelElement)
modelElement = temp;
else
temp = null;
} while (temp != null);
}
}
else if (otherEnd != null
&& otherEnd.getName().equals(step))
{
// take the step via
try
{
//String startPointName = startPoint.getName();
modelElement = takeAnchorPathStep(modelElement, step, otherEnd);
metaModelClass = /*(ResourceType)*/ otherEnd.getType();
metaModelClass.toString();
// stepTaken = true;
}
catch (Exception e)
{
logger.logException(e);
// do nothing - assumption was wrong & try next
}
// here was a problem because
// 'stepTaken = true' was here, before
}
else
{
// do nothing
}
}
// if (!stepTaken)
// return null;
}
/* until now, all steps have been taken
* but the first one in the array
* which is == 'self' (has been verified above)
*
* --> this is the anchor
*/
if (modelElement instanceof UmlClass)
{
logger.info("anchor of "
+ startPoint.getName()
+ " is: "
+ modelElement.getName());
return (UmlClass) modelElement;
}
else
{
logger.error("no anchor found for: " + startPoint.getName());
return null;
}
}
else
{
logger.error(MultiContextLogger.MODELMAPPER, "Invalid anchorPath: "
+ pathExpression);
}
return null;
}
/** finds the Anchor of a Resource and calculates
* the Resource's resourcePath
*
* @param resource
* @param startPointResourceType
* @return the anchor of the resource
*/
public UmlClass findAnchorOld(ModelElement resource,
ResourceType startPointResourceType)
{
if (resource == null || startPointResourceType == null)
{
resourcePath = "";
return null;
}
resourcePath = resource.getName();
ResourceType resourceType = startPointResourceType;
ModelElement modelElement = resource;
// TODO: follow startPointResourceType.getAnchorPath()
// from startPoint
String anchorPath = startPointResourceType.getAnchorPath();
String[] anchorPathSteps = null;
if (anchorPath != null)
{
anchorPathSteps = anchorPath.split("\\.");
}
//ModelElement anchor;
if (anchorPathSteps != null && anchorPath.length() > 0
&& anchorPathSteps[0].equals(MetaModelConst.SELF_PATH))
{
for (int i = 1; i < anchorPathSteps.length; i++)
{
String step = anchorPathSteps[i];
// boolean stepTaken = false;
Collection associations = dialectMetaModelInfo
.getInterResourceAssociations(resourceType);
for (Iterator iter = associations.iterator(); iter.hasNext();)
{
InterResourceAssociation association = (InterResourceAssociation) iter
.next();
ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.AssociationEnd otherEnd =
association.getOtherEnd(resourceType);
if (step.endsWith("*"))
{
step = step.substring(0, step.length() - 1);
//Collection c = navigateAssociation(modelElement, otherEnd);
ModelElement temp = null;
do // take this step 0-n times, as long as it leads somewhere else
{
temp =
takeAnchorPathStep(modelElement, step, otherEnd);
if(temp != null && temp != modelElement)
modelElement = temp;
else
temp = null;
} while (temp != null);
}
else if (otherEnd.getName().equals(step))
{
// take the step via
try
{
String startPointName = resource.getName();
modelElement = takeAnchorPathStep(modelElement, step, otherEnd);
resourceType = (ResourceType) otherEnd.getType();
resourceType.toString();
// stepTaken = true;
}
catch (Exception e)
{
logger.logException(e);
// do nothing - assumption was wrong & try next
}
// here was a problem because
// 'stepTaken = true' was here, before
}
else
{
// do nothing
}
}
// if (!stepTaken)
// return null;
}
/* until now, all steps have been taken
* but the first one in the array
* which is == 'self' (has been verified above)
*
* --> this is the anchor
*/
if (modelElement instanceof UmlClass)
return (UmlClass) modelElement;
else
return null;
}
else
{
logger.error(MultiContextLogger.MODELMAPPER, "Invalid anchorPath: "
+ anchorPath);
}
return null;
}
/**
* @param modelElement
* @param step
* @param otherEnd
* @return ModelElement which is reached by taking the step
*/
private ModelElement takeAnchorPathStep(
ModelElement modelElement,
String step,
ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.AssociationEnd otherEnd)
{
Collection c = null;
c = navigateAssociation(modelElement, otherEnd);
if (c == null)
return null;
else
// if (c instanceof Collection)
{
/*
* consider only the first element - anchor path must be unique
*/
Collection collection = (Collection) c;
if (collection.size() > 1)
{
logger.error(MultiContextLogger.MODELMAPPER,
"Anchor Path Step: " + step + " not unique.");
//return null;
}
else if (collection.size() == 0)
{
logger.error(MultiContextLogger.MODELMAPPER,
"Anchor Path Step: " + step + "could not be followed.");
//return null;
}
else
// collection.size == 1
{
Object o = collection.iterator().next();
if (o instanceof ModelElement)
{
modelElement = (ModelElement) o;
if (resourcePath == null || resourcePath.length() == 0)
{
resourcePath = modelElement.getName();
}
else
{
resourcePath = modelElement.getName() + "."
+ resourcePath;
}
// logger.info("step taken: " + step
// + ", resourcePath so far: " + resourcePath);
//break;
}
}
}
return modelElement;
}
// public String getResourcePath(ModelElement resourceUml)
// {
//
// UmlClass anchor = findAnchor(resourceUml);
//
// return resourcePath;
// }
// public UmlClass findClass(RefPackage umlPackage, String name)
// {
// if (umlPackage == null || umlPackage.getOwnedElement() == null)
// return null;
//
// //tudresden.ocl20.core.jmi.uml15.core.Namespace n;
// for (Iterator iter = umlPackage.getOwnedElement().iterator(); iter
// .hasNext();)
// {
// Object item = iter.next();
//
// if (item instanceof UmlClass)
// {
// UmlClass umlClass = (UmlClass) item;
//
// if (umlClass.getName().equals(name))
// return (UmlClass) umlClass;
//
// logger.info(" ! " + umlClass.getName());
// }
// else if (item instanceof RefPackage)
// {
// UmlClass result = findClass((RefPackage) item, name);
//
// if (result != null)
// return result;
// }
//
// // else
// // {
// // try
// // {
// // Class[] argTypes = new Class[0];
// // Object[] args = new Object[0];
// //
// // Method m = item.getClass().getMethod("getName", argTypes);
// // logger.info(" ! " + m.invoke(item, args) + " : " + item.getClass());
// // }
// // catch (Exception e)
// // {
// // //logger.logException(e);
// // //logger.info(" ! " + item.getClass());
// // }
// }
//
// // for (Iterator iterator = umlNamespace.getOwnedElement().iterator(); iter.hasNext();)
// // {
// // RefPackage refPackage = (RefPackage) iterator.next();
// //
// // UmlClass result = findClass(refPackage, name);
// // if(result != null)
// // return result;
// //
// // }
//
// return null;
// }
// public RefPackage findPackage(Collection packages, String name)
// {
// for (Iterator iter = packages.iterator(); iter.hasNext();)
// {
// Object item = iter.next();
// if (item instanceof Package)
// {
// RefPackage p = (RefPackage) item;
// String packagename = p.getName();
//
// if (packagename.equals(name))
// return p;
//
// RefPackage result = findPackage(p, name);
// if (result != null)
// return result;
// }
// }
// return null;
// }
//
// public RefPackage findPackage(RefPackage umlPackage, String name)
// {
// if (umlPackage == null || umlPackage.getOwnedElement() == null)
// return null;
//
// for (Iterator iter = umlPackage.getOwnedElement().iterator(); iter
// .hasNext();)
// {
// Object item = iter.next();
//
// if (item instanceof RefPackage)
// {
// RefPackage p = (RefPackage) item;
//
// String pName = p.getName();
// if (pName.equals(name))
// return p;
// else
// {
// logger.info(" ! " + p.getName());
// RefPackage result = findPackage((RefPackage) item, name);
// }
// }
// }
// return null;
// }
public String findPackage(ModelElement elem)
{
Namespace result = null;
while (result == null)
{
result = elem.getNamespace();
elem = (ModelElement) elem.refImmediateComposite();
}
if (elem instanceof Classifier)
{
result = elem.getNamespace();
}
return result.getName();
}
public Namespace findNamespaceByName(ModelElement startpoint, String name)
{
//Namespace result = null;
try
{
Collection elements = startpoint.getNamespace().getOwnedElement();
for (Iterator iter = elements.iterator(); iter.hasNext();)
{
Object item = (Object) iter.next();
if (item instanceof Namespace)
{
Namespace ns = (Namespace) item;
if(ns.getName().equals(name))
return ns;
}
}
}
catch (Exception e)
{
logger.logException(e);
}
return null;
}
public Collection navigateAssociation(ModelElement from,
InterResourceAssociation association)
{
MetaModelClass mmc = getMetaModelClass(from);
if (mmc != null)
{
AssociationEnd otherEnd = association.getOtherEnd(mmc);
if (otherEnd != null)
return navigateAssociation(from, otherEnd);
}
return null;
}
/**
* @param from
* @param targetAssociationEnd
* @return if the Association could not be navigated,
* 'null' is returned
*/
public Collection navigateAssociation(
ModelElement from,
ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.
AssociationEnd targetAssociationEnd)
{
if(from == null || targetAssociationEnd == null)
{
logger.error("navigateAssociation: null argument ("
+ from + ", " + targetAssociationEnd + ")");
return null;
}
String methodName = targetAssociationEnd.getUmlPropertyGetter();
Object result = null;
try
{
Method umlPropertyGetter = null;
if(methodName != null && methodName.length() != 0)
{
umlPropertyGetter =
from.getClass().getMethod(
methodName, new Class[0]);
result = umlPropertyGetter.invoke(from, new Object[0]);
}
// else
if(result == null ||
(result instanceof Collection
&& ((Collection)result).size() == 0))
// try to navigate backwards
{
// logger.info(
// "navigateAssociation - Navigating backwards:"
// + " using Method "
//+ targetAssociationEnd.getOwner());
// AssociationEnd otherEnd = targetAssociationEnd.
// getOwner().getOtherEnd(targetAssociationEnd.getType());
AssociationEnd otherEnd =
targetAssociationEnd.getOwner().getEnd1();
if(otherEnd == targetAssociationEnd)
otherEnd =
targetAssociationEnd.getOwner().getEnd2();
methodName =
otherEnd.getUmlPropertyGetter();
if(methodName != null && methodName.length() != 0)
{
// logger.info(
// "navigateAssociation - Navigating backwards:"
// + " using Method " + methodName);
Collection/*<ModelElement>*/ relatedElements =
new LinkedList/*<ModelElement>*/();
result = relatedElements;
Set<RefObject> allUmlElements =
ModelMap.getDefault().getAllUmlElements();
// logger.info("trying to start from "
//+ allUmlElements.size() + " Uml ModelElements "
//+ " via Method " + methodName);
for (Iterator iter = allUmlElements.iterator(); iter.hasNext();)
{
RefObject modelElement = (RefObject) iter.next();
//MetaModelClass mmc = getMetaModelClass(modelElement);
//if(mmc == )
//result == null;
try
{
umlPropertyGetter = modelElement.getClass().
getMethod(methodName,new Class[0]);
Object res = umlPropertyGetter.invoke(
modelElement, new Object[0]);
if (res instanceof ModelElement)
{
ModelElement resMe = (ModelElement) res;
logger.info(" ... invoked - method returned: "
+ resMe.getName());
}
if (res instanceof Collection)
{
Collection resultCollection = (Collection) result;
if(resultCollection.contains(from))
{
//result = modelElement;
//break;
relatedElements.add(modelElement);
}
}
else if (res != null)
{
if(res == from)
{
// result = modelElement;
// break;
relatedElements.add(modelElement);
}
}
}
catch (Exception e)
{
//logger.logException(e);
}
//result = null;
}
}
}
// if (result instanceof Collection)
// {
// // only consider the first element
// result = ((Collection) result).iterator().next();
// }
// if (result instanceof ModelElement)
// {
// modelElement = (ModelElement) result;
//
// }
}
catch (Exception e)
{
logger.error("Problem navigating AssociationEnd "
+ targetAssociationEnd
+ " from " + from.getName());
logger.logException(e);
}
if (result instanceof Collection)
return (Collection) result;
else if (result != null)
{
LinkedList<Object> l = new LinkedList<Object>();
l.add(result);
return l;
}
else
return null;
}
/* utility methods */
public boolean hasType(ModelElement modelElement, String className)
{
className += MetaModelConst.MDR_IMPL_SUFFIX;
// logger.info("hasType("
// + modelElement.getClass().getSimpleName()
// + ", "
// + className);
if (modelElement != null && className != null)
{
boolean result = modelElement.getClass().getSimpleName().
startsWith(className);
// logger.info("... " + result);
return result;
}
else
return false;
}
public boolean hasStereotype(ModelElement element, String stereotype)
{
if (element == null || stereotype == null || stereotype.length() == 0)
return false;
Collection stereotypes = element.getStereotype();
int nofStereotypes = stereotypes.size();
// logger.info("hasStereotype(sterotype:" + stereotype
// + " - searching among " + nofStereotypes);
if (stereotypes == null || stereotypes.size() == 0)
return false;
for (Iterator it = stereotypes.iterator(); it.hasNext();)
{
Stereotype s = (Stereotype) it.next();
if (s.getName().equals(stereotype))
{
// logger.info("... found");
return true;
}
}
return false;
}
public boolean haveStereotype(Collection<ModelElement> elements,
String stereotype)
{
for (ModelElement elem : elements)
{
if (!hasStereotype(elem, stereotype))
{
return false;
}
}
return true;
}
/**
* @return the map
*/
public MetaModelMap getMap()
{
return map;
}
/**
* @param map the map to set
*/
public void setMap(MetaModelMap map)
{
this.map = map;
}
/**
* @return the dialectMetaModelInfo
*/
public DialectMetaModelInfo getDialectMetaModelInfo()
{
return dialectMetaModelInfo;
}
/**
* @param dialectMetaModelInfo the dialectMetaModelInfo to set
*/
public void setDialectMetaModelInfo(DialectMetaModelInfo dialectMetaModelInfo)
{
this.dialectMetaModelInfo = dialectMetaModelInfo;
}
/**
* @return the resourcePath
*/
public String getResourcePath()
{
return resourcePath;
}
public String getResourcePath(ModelElement resourceUml)
{
UmlClass anchor = findAnchor(resourceUml);
// generic solution, doesn't work correctly
// MetaModelClass anchorMetaModelClass = getMetaModelClass(anchor);
//
// ResourceType resourceType = getResourceType(resourceUml);
//
// if(resourceType != null && resourceType.getResoucePath() != null)
// {
// OclExpressionsParser parser = new OclExpressionsParser();
//
// try
// {
// OclExpression resourcePathExpression =
// parser.parseOclExpression(resourceType.getResoucePath());
//
// OclUmlExpressionEvaluator evaluator =
// new OclUmlExpressionEvaluator(
// resourcePathExpression, anchor, anchor,
// dialectMetaModelInfo, anchorMetaModelClass);
//
// Set reachedObjects = evaluator.evaluateExpression();
//
// Object resourceUmlObject = findElementByName(reachedObjects, resourceUml.getName());
// if(evaluator.getResourcePaths().containsKey(resourceUmlObject))
// {
// resourcePath = evaluator.getResourcePaths().get(resourceUmlObject);
// logger.info("##resourcePath for "
// + resourceUml.getName()
// + " recalucalated: "
// + resourcePath);
// }
// else
// // ugly, non-generic hack
// {
// String[] resourcePathFragments = resourcePath.split("\\.");
// resourcePath = resourcePathFragments[0]
// + "." + resourcePathFragments[1];
// }
// }
// catch (Exception e)
// {
// e.printStackTrace();
// }
// }
// ugly, non-generic hack
String[] resourcePathFragments = resourcePath.split("\\.");
if(resourcePathFragments.length == 1)
return resourcePathFragments[0];
else
{
resourcePath = resourcePathFragments[0]
+ "." + resourcePathFragments[1];
return resourcePathFragments[0]
+ "." + resourcePathFragments[1];
}
//return resourcePath;
}
/**
* Find a resource in a modelelement according to the given pathName.
*
* @param pathName
* @param anchor
* @return the found element
*/
@SuppressWarnings("unchecked")
public ModelElement resolvePath(
String pathName, ModelElement anchor)
{
logger.info("resolving resource Path: '" + pathName +
"' starting at " + anchor.getName());
String[] components = pathName.split("\\.");
if (components.length == 0)
{
logger.error("invalid path expression: " + pathName);
return null;
}
int pathOffset = 0;
if (components[pathOffset].equals(anchor.getName()))
{
if (components.length == 1)
{
// path name denotes the anchor, return it
return anchor;
}
else
{
// path name has an anchor prefix, skip it
pathOffset = 1;
}
}
ModelElement result = anchor;
// follow path to find resource
while (pathOffset < components.length)
{
result = findRelatedElement(
result, components[pathOffset]);
pathOffset++;
}
if (result == null)
{
logger.error("invalid path expression - target not found: " + pathName);
}
return result;
}
/**
* Finds an element with the given name inside its containing object.
*
* @param startPoint
* @param name
* @return the found element
*/
@SuppressWarnings("unchecked")
private ModelElement findRelatedElement(
ModelElement startPoint,
String name)
{
if(startPoint == null)
{
logger.error("findRelatedElement - start point null, name = "+name);
return null;
}
logger.info("searching related Element with Name '" + name +
"' starting from "+startPoint.getName() + "'");
MetaModelClass metaModelClass =
getMetaModelClass(startPoint);
if(metaModelClass == null)
{
logger.error(startPoint.getName()
+ " is not a metaModelClass Instance");
return null;
} else {
logger.info("startPoint is a '"+metaModelClass.getName()+"' instance");
}
for (Iterator iter =
dialectMetaModelInfo.getInterResourceAssociations(
metaModelClass).iterator(); iter.hasNext();)
{
InterResourceAssociation association =
(InterResourceAssociation) iter.next();
// logger.info("... along " + association.getName());
Collection result = navigateAssociation(startPoint, association);
// if(result != null)
// logger.info("...among " + result.size() + " elements");
ModelElement relatedElement = findElementByName(result, name);
if(relatedElement != null)
return relatedElement;
else
{
result = new LinkedList();
Set<RefObject> allUmlElements =
ModelMap.getDefault().getAllUmlElements();
for (Iterator it = allUmlElements.iterator(); it.hasNext();)
{
RefObject item = (RefObject) it.next();
if (item instanceof ModelElement)
{
ModelElement modelElement = (ModelElement) item;
Classifier anchor = findAnchor(modelElement);
if(anchor == startPoint)
{
result.add(modelElement);
}
}
}
relatedElement = findElementByName(result, name);
if(relatedElement != null)
return relatedElement;
}
// else
// {
// AssociationEnd otherEnd =
// association.getOtherEnd(metaModelClass);
// AssociationEnd end =
// association.getOtherEnd(otherEnd.getType());
//
// Collection<ModelElement> relatedElements =
// new LinkedList<ModelElement>();
//// tryNavigateBackwards(otherEnd, end,
//// Model.getCoreHelper().
//// getAllClassifiers(startPoint.getNamespace())
//// , startPoint);
// Set<RefObject> allUmlElements =
// ModelMap.getDefault().getAllUmlElements();
//
//
// return findElementByName(relatedElements, name);
//
// //return relatedElement;
// }
}
// org.omg.uml.foundation.core.AssociationEnd a;
// a.getParticipant();
return null;
}
private ModelElement findElementByName(Collection<ModelElement> elems, String name) {
if(elems == null)
return null;
for (ModelElement elem : elems)
{
if (elem == null)
{
logger.info("elem==null in findElementByName");
}
if(elem.getName()==null) {
logger.error("elem.getName() == null in findElementByName");
if ("".equals(name))
return elem;
} else if (elem.getName().equals(name))
{
return elem;
}
else
{
// logger.info("... is not: " + elem.getName());
}
}
return null;
}
private Collection<ModelElement> tryNavigateBackwards(
AssociationEnd otherEnd,
AssociationEnd end,
Collection modelElements,
ModelElement target)//,int maxDepth)
{
Set visitedElements = new LinkedHashSet();
return tryNavigateBackwards(
otherEnd, end, modelElements,
visitedElements, target);
}
/**
* @param otherEnd
* @param end
* @param modelElements
*/
private Collection<ModelElement> tryNavigateBackwards(
AssociationEnd otherEnd, AssociationEnd end,
Collection modelElements, Set visitedElements,
ModelElement target)
{
Collection<ModelElement> res = new LinkedList();
// if(maxDepth <= 0)
// return;
if(modelElements == null || modelElements.size() == 0)
return null;
// logger.info(logger.MODELMAPPER_DETAILLED,
// "Try to navigate Association the other way round - "
// + "iterating over all ModelElements in the Namespace - n = "
// + modelElements.size());
for (Iterator iterator = modelElements.iterator(); iterator
.hasNext();)
{
Object object = iterator.next();
// if (object instanceof Namespace)
// {
// Namespace ns = (Namespace) object;
// tryNavigateBackwards(otherEnd, end, ns.getOwnedElement());
////
//// Util.addAllSave(allElementsInNamespace, ns.getOwnedElement());
// }
// TODO: replace this hardcoded hack by a generic solution
if (object instanceof ModelElement)
{
ModelElement m = (ModelElement) object;
if(visitedElements.contains(m))
return null;
else
visitedElements.add(m);
if (hasType(m, otherEnd.getType().getName()))
{
logger
.info("try to navigate Association in reverse Direction " +
"from end: "
+ otherEnd.getName());
Collection coll = navigateAssociation(m, end);
String s = "... leads to: ";
if(coll.size()>1)
s = s + " Collection containing: ";
if(coll.size() > 0)
s = s + Util.getProperty(coll.iterator().next(), "name");//+ coll);
logger.info(s);
// if (coll instanceof Collection)
// {
if(coll != null)
{
//Collection c1 = (Collection) coll;
//addModelElementsToScope(otherEnd, coll);
if(coll.contains(target))
{
res.add(m);
}
// TODO: do something here
//addModelElementToScope(otherEnd, m);
}
// else if (c1 instanceof ModelElement)
// {
// try
// {
// addModelElementToScope(otherEnd, m);
// }
// catch (Exception e)
// {
// ;
// }
//
// }
}
else
{
//
// if(m instanceof Association)
// {
// Association a = (Association) m;
//
// tryNavigateBackwards(otherEnd, end, a.getConnection(), maxDepth/1);
//
////
//// Util.addAllSave(allElementsInNamespace, a.getConnection());
// }
// logger.info("wrong type: "
// + m.getClass().getSimpleName()
// + " : " + m.getName());
// logger.info(
// "can't reach the ModelElement directly, " +
// "try to reach it in several hops...");
// but can try to reach the source ModelElement via
// more than one step
MetaModelClass mmClass = getMetaModelClass(m);
if(mmClass != null && mmClass.getUmlClassName() != null)
{
// logger.info("...from: "
// + m.getClass().getSimpleName()
// + " : "
// + m.getNameA());
Collection associations = dialectMetaModelInfo.getInterResourceAssociations(mmClass);
if(associations != null)
{
for (Iterator iter = associations.iterator(); iter.hasNext();)
{
InterResourceAssociation association = (InterResourceAssociation) iter.next();
Collection<ModelElement> result =
navigateAssociation(
m, association.getOtherEnd(mmClass));
// Collection coll;
// if (result instanceof Collection)
// {
// coll = (Collection) result;
//
// }
// else
// {
// coll = new LinkedList(); coll.add(result);
// }
//tryNavigateBackwards(otherEnd, end, coll, maxDepth-1);
return tryNavigateBackwards(otherEnd, end, result, visitedElements, target);
}
}
}
}
}
}
return res;
}
}