/***************************************************************************** * Copyright (c) 2011 CEA LIST. * * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * CEA LIST - Initial API and implementation * *****************************************************************************/ package org.eclipse.papyrus.uml.alf.scoping; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import org.eclipse.emf.ecore.EObject; import org.eclipse.papyrus.uml.alf.alf.AcceptClause; import org.eclipse.papyrus.uml.alf.alf.AcceptStatement; import org.eclipse.papyrus.uml.alf.alf.DocumentedStatement; import org.eclipse.papyrus.uml.alf.alf.InvocationOrAssignementOrDeclarationStatement; import org.eclipse.papyrus.uml.alf.alf.LocalNameDeclarationStatement; import org.eclipse.papyrus.uml.alf.alf.LoopVariableDefinition; import org.eclipse.papyrus.uml.alf.alf.SequenceExpansionExpression; import org.eclipse.papyrus.uml.alf.alf.Statement; import org.eclipse.papyrus.uml.alf.validation.AlfJavaValidator; import org.eclipse.papyrus.uml.alf.validation.typing.TypeExpression; import org.eclipse.papyrus.uml.alf.validation.typing.TypeUtils; import org.eclipse.uml2.uml.Behavior; import org.eclipse.uml2.uml.Class; import org.eclipse.uml2.uml.Classifier; import org.eclipse.uml2.uml.Element; import org.eclipse.uml2.uml.ElementImport; import org.eclipse.uml2.uml.Enumeration; import org.eclipse.uml2.uml.EnumerationLiteral; import org.eclipse.uml2.uml.NamedElement; import org.eclipse.uml2.uml.Namespace; import org.eclipse.uml2.uml.Operation; import org.eclipse.uml2.uml.Package; import org.eclipse.uml2.uml.PackageImport; import org.eclipse.uml2.uml.PackageableElement; import org.eclipse.uml2.uml.Property; import org.eclipse.uml2.uml.Reception; import org.eclipse.uml2.uml.Signal; import org.eclipse.uml2.uml.VisibilityKind; public abstract class AlfScopingTool { protected static List<EObject> removeDuplicateClassifiers(List<EObject> list) { List<EObject> intermediateFilteredList = new ArrayList<EObject>() ; HashMap<String, Classifier> classifiers = new HashMap<String, Classifier>() ; HashMap<String, Classifier> elementImports = new HashMap<String, Classifier>() ; for (EObject o : list) { if (o instanceof Classifier) { Classifier c = (Classifier) o ; if (classifiers.get(c.getQualifiedName()) == null) { classifiers.put(c.getQualifiedName(), c) ; intermediateFilteredList.add(c) ; } // else => nothing to be done, this is a duplicate } else if (o instanceof ElementImport) { ElementImport e = (ElementImport)o ; Classifier c = (Classifier)e.getImportedElement() ; if (elementImports.get(e.getAlias()) == null) { elementImports.put(e.getAlias(), c) ; intermediateFilteredList.add(e) ; } else {// need to check if element import aliases the same thing. Classifier alreadyInTheList = elementImports.get(e.getAlias()) ; if (! alreadyInTheList.getQualifiedName().equals(c.getQualifiedName())) { // The model is ill-formed, and there's no need to filter intermediateFilteredList.add(e) ; } // else => nothing to be done, this is a duplicate } } } // needs to make a second pass on the filtered list, to remove cases where aliases and names are the same, and represent the same element List<EObject> filteredList = new ArrayList<EObject>() ; for (int i = 0 ; i < intermediateFilteredList.size() ; i++) { String classifierName = (intermediateFilteredList.get(i) instanceof Classifier) ? ((Classifier)intermediateFilteredList.get(i)).getName() : ((ElementImport)intermediateFilteredList.get(i)).getAlias() ; String classifierQualifiedName = (intermediateFilteredList.get(i) instanceof Classifier) ? ((Classifier)intermediateFilteredList.get(i)).getQualifiedName() : ((Classifier)((ElementImport)intermediateFilteredList.get(i)).getImportedElement()).getQualifiedName() ; boolean duplicateFound = false ; for (int j = i + 1 ; j < intermediateFilteredList.size() && !duplicateFound ; j++) { String cddDuplicateClassifierName = (intermediateFilteredList.get(j) instanceof Classifier) ? ((Classifier)intermediateFilteredList.get(j)).getName() : ((ElementImport)intermediateFilteredList.get(j)).getAlias() ; if (cddDuplicateClassifierName.equals(classifierName)) { String cddDuplicateClassifierQualifiedName = (intermediateFilteredList.get(j) instanceof Classifier) ? ((Classifier)intermediateFilteredList.get(j)).getQualifiedName() : ((Classifier)((ElementImport)intermediateFilteredList.get(j)).getImportedElement()).getQualifiedName() ; if (cddDuplicateClassifierQualifiedName.equals(classifierQualifiedName)) { duplicateFound = true ; } } } if (!duplicateFound) filteredList.add(intermediateFilteredList.get(i)) ; } return filteredList ; } public abstract AlfPartialScope getVisibleVariablesOrParametersOrProperties(EObject context) ; public AlfPartialScope getVisibleOperationsOrBehaviors(EObject context) { AlfPartialScope.IGetNameStrategy nameStrategy = new OperationAndBehaviorNameStrategy() ; AlfPartialScope.IBuildScopeStrategy buildScopeStrategy = new OperationAndBehaviorBuildScopeStrategy() ; return new AlfPartialScope(nameStrategy, buildScopeStrategy, context) ; } public AlfPartialScope getVisibleBehaviors(EObject context) { AlfPartialScope.IGetNameStrategy nameStrategy = new BehaviorsNameStrategy() ; AlfPartialScope.IBuildScopeStrategy buildScopeStrategy = new BehaviorsBuildScopeStrategy() ; return new AlfPartialScope(nameStrategy, buildScopeStrategy, context) ; } public AlfPartialScope getVisibleClassifiers(EObject context) { AlfPartialScope.IGetNameStrategy nameStrategy = new ClassifiersNameStrategy() ; AlfPartialScope.IBuildScopeStrategy buildScopeStrategy = new ClassifiersBuildScopeStrategy() ; return new AlfPartialScope(nameStrategy, buildScopeStrategy, context) ; } public AlfPartialScope getVisiblePackages(EObject context) { if (context instanceof Package) { AlfPartialScope.IGetNameStrategy nameStrategy = new PackageNameStrategy() ; AlfPartialScope.IBuildScopeStrategy buildScopeStrategy = new PackagesBuildScopeStrategy() ; return new AlfPartialScope(nameStrategy, buildScopeStrategy, context) ; } AlfPartialScope.IGetNameStrategy nameStrategy = new PackageNameStrategy() ; AlfPartialScope.IBuildScopeStrategy buildScopeStrategy = new PackagesBuildScopeStrategy() ; return new AlfPartialScope(nameStrategy, buildScopeStrategy, context) ; } public boolean isAReturnStatementExpected(EObject context) { return false ; } public TypeExpression getExpectedReturnType(EObject context) { return null; } public AlfPartialScope getVisibleSignalReceptions(EObject context) { AlfPartialScope.IGetNameStrategy nameStrategy = new ReceptionsNameStrategy() ; AlfPartialScope.IBuildScopeStrategy buildScopeStrategy = new ReceptionsBuildScopeStrategy() ; return new AlfPartialScope(nameStrategy, buildScopeStrategy, context); } /* * Strategies for operations */ protected class OperationAndBehaviorNameStrategy implements AlfPartialScope.IGetNameStrategy { public String getName(EObject element) { if (element instanceof Operation) return ((Operation)element).getName(); else if (element instanceof Behavior) return ((Behavior)element).getName() ; else if (element instanceof ElementImport) { ElementImport eImport = (ElementImport)element ; if (eImport.getAlias() != null) return eImport.getAlias() ; else return ((Behavior)eImport.getImportedElement()).getName() ; } else if (element instanceof Reception) { return ((Reception)element).getName() ; } else return "Unexpected element kind..." ; } }; protected class OperationAndBehaviorBuildScopeStrategy implements AlfPartialScope.IBuildScopeStrategy { public List<List<EObject>> buildScope(EObject contextElement) { List<List<EObject>> nestedScopes = new ArrayList<List<EObject>>() ; List<EObject> nestedList = new ArrayList<EObject>() ; // in the case where the context element is a Package or an ElementImport for a package, the scope can only contain behaviors Package potentialContextPackage = null ; if (contextElement instanceof Package) { potentialContextPackage = (Package)contextElement ; } else if (contextElement instanceof ElementImport) { ElementImport eImport = (ElementImport)contextElement ; if (eImport.getImportedElement() instanceof Package) potentialContextPackage = (Package)eImport.getImportedElement() ; } if (potentialContextPackage != null) { AlfPartialScope behaviorScope = AlfScopeProvider.scopingTool.getVisibleBehaviors(contextElement) ; for (List<EObject> scope : behaviorScope.getScopeDetails()) { nestedScopes.add(scope) ; } return nestedScopes ; } // At this point, we have identified that the context element is not a package. // First scoping levels concern operations // retrieves the contextClassier (i.e. the owner of the contextOperation, or contextElement) Classifier contextClassifier ; if (contextElement instanceof Classifier) { contextClassifier = (Classifier)contextElement ; } else if (contextElement instanceof ElementImport && ((ElementImport)contextElement).getImportedElement() instanceof Classifier) { contextClassifier = (Classifier) ((ElementImport)contextElement).getImportedElement() ; } else { contextClassifier = AlfJavaValidator.getContextClassifier() ; } // add all the operations owned by the context classifier at the first scoping level nestedList.addAll(contextClassifier.getOperations()) ; // adds also receptions if (contextClassifier instanceof org.eclipse.uml2.uml.Class) { nestedList.addAll(((Class)contextClassifier).getOwnedReceptions()) ; } nestedScopes.add(nestedList) ; // then builds other scoping levels based on context classifier inheritance hierarchy List<Classifier> currentGenerals = new ArrayList<Classifier>() ; currentGenerals.addAll(contextClassifier.getGenerals()) ; List<Classifier> nextGenerals ; while (!currentGenerals.isEmpty()) { nextGenerals = new ArrayList<Classifier>() ; nestedList = new ArrayList<EObject>() ; for (Classifier general : currentGenerals) { nextGenerals.addAll(general.getGenerals()) ; for (Operation o : general.getOperations()) nestedList.add(o) ; if (general instanceof Class) { for (Reception r : ((Class)general).getOwnedReceptions()) { nestedList.add(r) ; } } } nestedScopes.add(nestedList) ; currentGenerals = nextGenerals ; } // finally feeds last scoping levels with behaviors (only if contextElement is not a Class) if (! ((contextElement instanceof Classifier) || ((contextElement instanceof ElementImport && ((ElementImport)contextElement).getImportedElement() instanceof Classifier)))) { AlfPartialScope behaviorScope = AlfScopeProvider.scopingTool.getVisibleBehaviors(contextElement) ; for (List<EObject> scope : behaviorScope.getScopeDetails()) { nestedScopes.add(scope) ; } } return nestedScopes ; } } /* * Strategies for Receptions */ protected class ReceptionsNameStrategy implements AlfPartialScope.IGetNameStrategy { public String getName(EObject element) { if (element instanceof Signal) return ((Signal)element).getName(); else return "Unexpected element kind..." ; } }; protected class ReceptionsBuildScopeStrategy implements AlfPartialScope.IBuildScopeStrategy { public List<List<EObject>> buildScope(EObject contextElement) { List<List<EObject>> nestedScopes = new ArrayList<List<EObject>>() ; List<EObject> nestedList = new ArrayList<EObject>() ; // retrieves the owner of the contextOperation Classifier contextClassifier = AlfJavaValidator.getContextClassifier() ; if (! (contextClassifier instanceof org.eclipse.uml2.uml.Class)) { nestedScopes.add(nestedList) ; return nestedScopes ; } // add all the signals for which a Reception is defined for (org.eclipse.uml2.uml.Feature f : contextClassifier.allFeatures()) { if (f instanceof Reception) if (((Reception)f).getSignal() != null) nestedList.add(((Reception)f).getSignal()) ; } nestedScopes.add(nestedList) ; return nestedScopes ; } } /* * Strategies for Variables, Parameters and Properties */ protected class VariableOrParameterOrPropertyNameStrategy implements AlfPartialScope.IGetNameStrategy { public String getName(EObject element) { if (element instanceof Property) return ((Property)element).getName(); else if (element instanceof LocalNameDeclarationStatement){ return ((LocalNameDeclarationStatement)element).getVarName() ; } else if (element instanceof InvocationOrAssignementOrDeclarationStatement) { InvocationOrAssignementOrDeclarationStatement statement = (InvocationOrAssignementOrDeclarationStatement)element ; return statement.getVariableDeclarationCompletion() != null ? statement.getVariableDeclarationCompletion().getVariableName() : "" ; } else if (element instanceof LoopVariableDefinition) { return ((LoopVariableDefinition)element).getName() ; } else if (element instanceof AcceptClause) { return ((AcceptClause)element).getName() ; } else if (element instanceof AcceptStatement) { return ((AcceptStatement)element).getClause().getName() ; } else if (element instanceof SequenceExpansionExpression) { SequenceExpansionExpression expression = (SequenceExpansionExpression)element ; return expression.getName() != null ? expression.getName() : "" ; } return "unexpected kind ..." ; } } protected abstract class VariableOrPropertyOrParameterBuildScopeStrategy implements AlfPartialScope.IBuildScopeStrategy { public abstract List<List<EObject>> buildScope(EObject contextElement) ; public boolean containsALocalNameDeclaration(DocumentedStatement previousDocumentStatement) { Statement statement = previousDocumentStatement.getStatement() ; if (statement instanceof LocalNameDeclarationStatement) return true ; if (statement instanceof InvocationOrAssignementOrDeclarationStatement) { //TODO : handle cases with implicit declarations, e.g., v = 14 ; // v is a variable of type Integer InvocationOrAssignementOrDeclarationStatement cddDclStatement = (InvocationOrAssignementOrDeclarationStatement)statement; if (cddDclStatement.getVariableDeclarationCompletion() != null) { return true ; } } if (statement instanceof AcceptStatement) { AcceptStatement cddDclStatement = (AcceptStatement)statement ; if (cddDclStatement.getSimpleAccept() != null && cddDclStatement.getClause().getName() != null) return true ; } return false; } } /* * Strategies for Classifiers */ protected class ClassifiersNameStrategy implements AlfPartialScope.IGetNameStrategy { public String getName(EObject element) { if (element instanceof Classifier) return ((Classifier)element).getName() ; else if (element instanceof ElementImport) { ElementImport imported = (ElementImport)element ; return imported.getAlias() != null ? imported.getAlias() : ((Classifier)imported.getImportedElement()).getName() ; } else return "Unexpected element kind..." ; } }; protected class ClassifiersBuildScopeStrategy implements AlfPartialScope.IBuildScopeStrategy { public List<List<EObject>> buildScope(EObject contextElement) { List<List<EObject>> nestedScopes = new ArrayList<List<EObject>>() ; List<EObject> nestedList = new ArrayList<EObject>() ; // first checks if contextElement represents a Package. In this case, builds a scope containing all classifiers visible from this package Package potentialContextPackage = null ; if (contextElement instanceof Package) potentialContextPackage = (Package)contextElement ; else if (contextElement instanceof ElementImport) { ElementImport eImport = (ElementImport)contextElement ; if (eImport.getImportedElement() instanceof Package) potentialContextPackage = (Package)eImport.getImportedElement() ; } if (potentialContextPackage != null) { List<EObject> importedClassifiers = processPublicallyImportedClassifiers(potentialContextPackage) ; importedClassifiers = removeDuplicateClassifiers(importedClassifiers) ; nestedScopes.add(importedClassifiers) ; return nestedScopes ; } // retrieves the owner of the contextOperation Classifier contextClassifier = AlfJavaValidator.getContextClassifier() ; // add the context classifier at the first scoping level nestedList.add(contextClassifier) ; // retrieves all package imports, and add all classifiers available at the root of this package for (PackageImport i : contextClassifier.getPackageImports()) { Package importedPackage = i.getImportedPackage() ; nestedList.addAll(processPublicallyImportedClassifiers(importedPackage)) ; } // retrieves all element imports. For those which concern a Classifier, either add the classifier if no alias is defined, or the element import if an alias is defined for (ElementImport i : contextClassifier.getElementImports()) { PackageableElement e = i.getImportedElement() ; if (e instanceof Classifier) { if (i.getAlias() != null) nestedList.add(i) ; else nestedList.add(e) ; } } nestedList = removeDuplicateClassifiers(nestedList) ; nestedScopes.add(nestedList) ; // Then process the implicit import of alf library nestedList = new ArrayList<EObject>() ; if (AlfJavaValidator.getAlfStandardLibrary() != null) { List<EObject> importedClassifiers = processPublicallyImportedClassifiers(AlfJavaValidator.getAlfStandardLibrary()) ; importedClassifiers.add(TypeUtils._Collection.extractActualType()) ; importedClassifiers.add(TypeUtils._Set.extractActualType()) ; importedClassifiers.add(TypeUtils._Bag.extractActualType()) ; importedClassifiers.add(TypeUtils._Queue.extractActualType()) ; importedClassifiers.add(TypeUtils._OrderedSet.extractActualType()) ; importedClassifiers.add(TypeUtils._List.extractActualType()) ; importedClassifiers.add(TypeUtils._Deque.extractActualType()) ; importedClassifiers.add(TypeUtils._Map.extractActualType()) ; //importedClassifiers.add(TypeUtils._Entry.extractActualType()) ; nestedList.addAll(removeDuplicateClassifiers(importedClassifiers)) ; nestedScopes.add(nestedList) ; } // Then process all classifiers at the same namespace level than the context classifier nestedList = new ArrayList<EObject>() ; Namespace namespaceOfContextClassifier = contextClassifier.getNamespace() ; for (Element e : namespaceOfContextClassifier.getOwnedElements()) { if (e instanceof Classifier && e != contextClassifier) nestedList.add(e) ; } nestedScopes.add(nestedList) ; return nestedScopes ; } private List<EObject> processPublicallyImportedClassifiers (Package p){ List<EObject> importedClassifiers = new ArrayList<EObject>() ; for (NamedElement n : p.getOwnedMembers()) { if (n instanceof Classifier) if (((Classifier)n).getVisibility() != VisibilityKind.PRIVATE_LITERAL) { importedClassifiers.add(n) ; } } for (ElementImport eImport : p.getElementImports()) { if (eImport.getVisibility()!= VisibilityKind.PRIVATE_LITERAL) { PackageableElement element = eImport.getImportedElement() ; if (element instanceof Classifier) { if (eImport.getAlias() != null) { importedClassifiers.add(eImport) ; } else { importedClassifiers.add(element) ; } } } } for (PackageImport pImport : p.getPackageImports()) { if (pImport.getVisibility() != VisibilityKind.PRIVATE_LITERAL) { importedClassifiers.addAll(processPublicallyImportedClassifiers(pImport.getImportedPackage())) ; } } return importedClassifiers ; } } /* * Strategies for Packages */ protected class PackageNameStrategy implements AlfPartialScope.IGetNameStrategy { public String getName(EObject element) { if (element instanceof Namespace) return ((Namespace)element).getName() ; else if (element instanceof ElementImport) { ElementImport eImport = (ElementImport)element ; return eImport.getAlias() != null ? eImport.getAlias() : eImport.getImportedElement().getName() ; } else return "Unexpected element kind..." ; } } protected class PackagesBuildScopeStrategy implements AlfPartialScope.IBuildScopeStrategy { public List<List<EObject>> buildScope(EObject contextElement) { List<List<EObject>> nestedScopes = new ArrayList<List<EObject>>() ; List<EObject> nestedList = new ArrayList<EObject>() ; if (contextElement instanceof Package) { // if the context element is a package, returns the scope related to this package. nestedScopes.add(processPublicallyImportedPackages((Package)contextElement)) ; return nestedScopes ; } Package root = (Package)AlfJavaValidator.getModel() ; // first process packages directly imported by the context classifier (either package import or element import) Classifier contextClassifier = AlfJavaValidator.getContextClassifier() ; nestedList.addAll(processPublicallyImportedPackages(contextClassifier)) ; nestedScopes.add(nestedList) ; // Then process the implicit import of alf library nestedList = new ArrayList<EObject>() ; if (AlfJavaValidator.getAlfStandardLibrary() != null) { nestedList.add(AlfJavaValidator.getAlfStandardLibrary()) ; nestedList.addAll(processPublicallyImportedPackages(AlfJavaValidator.getAlfStandardLibrary())) ; nestedScopes.add(nestedList) ; } // finally processes the root package nestedList = new ArrayList<EObject>() ; nestedList.add(root) ; nestedScopes.add(nestedList) ; return nestedScopes; } protected List<EObject> processPublicallyImportedPackages (Namespace namespace) { List<EObject> importedPackages = new ArrayList<EObject>() ; for (NamedElement ownedMember : namespace.getOwnedMembers()) { if (ownedMember.getVisibility() != VisibilityKind.PRIVATE_LITERAL && ownedMember instanceof Package) importedPackages.add(ownedMember) ; } for (ElementImport eImport : namespace.getElementImports()) { if (eImport.getVisibility() != VisibilityKind.PRIVATE_LITERAL ) { PackageableElement importedElement = eImport.getImportedElement() ; if (importedElement instanceof Package) { if (eImport.getAlias() != null) importedPackages.add(eImport) ; else importedPackages.add(importedElement) ; } } } for (PackageImport pImport : namespace.getPackageImports()) { if (pImport.getVisibility() != VisibilityKind.PRIVATE_LITERAL) { importedPackages.addAll(processPublicallyImportedPackages(pImport.getImportedPackage())) ; } } return importedPackages ; } } /* * Strategies for Behaviors */ protected class BehaviorsNameStrategy implements AlfPartialScope.IGetNameStrategy { public String getName(EObject element) { if (element instanceof Behavior) return ((Behavior)element).getName() ; else if (element instanceof ElementImport) { ElementImport imported = (ElementImport)element ; return imported.getAlias() != null ? imported.getAlias() : ((Behavior)imported.getImportedElement()).getName() ; } else return "Unexpected element kind..." ; } }; protected class BehaviorsBuildScopeStrategy implements AlfPartialScope.IBuildScopeStrategy { public List<List<EObject>> buildScope(EObject contextElement) { List<List<EObject>> nestedScopes = new ArrayList<List<EObject>>() ; List<EObject> nestedList = new ArrayList<EObject>() ; // first checks if contextElement represents a Package. In this case, builds a scope containing all behaviors visible from this package Package potentialContextPackage = null ; if (contextElement instanceof Package) potentialContextPackage = (Package)contextElement ; else if (contextElement instanceof ElementImport) { ElementImport eImport = (ElementImport)contextElement ; if (eImport.getImportedElement() instanceof Package) potentialContextPackage = (Package)eImport.getImportedElement() ; } if (potentialContextPackage != null) { nestedScopes.add(processPublicallyImportedBehaviors(potentialContextPackage)) ; return nestedScopes ; } // retrieves the contextOperation (i.e., the operation edited by the current editor) // retrieves the owner of the contextOperation Classifier contextClassifier = AlfJavaValidator.getContextClassifier() ; // retrieves all package imports, and add all behaviors available at the root of this package for (PackageImport i : contextClassifier.getPackageImports()) { Package importedPackage = i.getImportedPackage() ; nestedList.addAll(processPublicallyImportedBehaviors(importedPackage)) ; } // retrieves all element imports. For those which concern a Behavior, either add the behavior if no alias is defined, or the element import if an alias is defined for (ElementImport i : contextClassifier.getElementImports()) { PackageableElement e = i.getImportedElement() ; if (e instanceof Classifier) { if (i.getAlias() != null) nestedList.add(i) ; else nestedList.add(e) ; } } nestedList = removeDuplicateClassifiers(nestedList) ; nestedScopes.add(nestedList) ; // Then process the implicit import of alf library nestedList = new ArrayList<EObject>() ; if (AlfJavaValidator.getAlfStandardLibrary() != null) { List<EObject> importedClassifiers = processPublicallyImportedBehaviors(AlfJavaValidator.getAlfStandardLibrary()) ; importedClassifiers = removeDuplicateClassifiers(importedClassifiers) ; nestedList.addAll(importedClassifiers) ; nestedScopes.add(nestedList) ; } return nestedScopes ; } private List<EObject> processPublicallyImportedBehaviors (Package p){ List<EObject> importedBehaviors = new ArrayList<EObject>() ; for (NamedElement n : p.getOwnedMembers()) { if (n instanceof Behavior) { if (((Behavior)n).getVisibility() != VisibilityKind.PRIVATE_LITERAL) importedBehaviors.add(n) ; } else if (n instanceof Package) { importedBehaviors.addAll(processPublicallyImportedBehaviors((Package)n)) ; } } for (ElementImport eImport : p.getElementImports()) { if (eImport.getVisibility()!= VisibilityKind.PRIVATE_LITERAL) { PackageableElement element = eImport.getImportedElement() ; if (element instanceof Behavior) { if (eImport.getAlias() != null) importedBehaviors.add(eImport) ; else importedBehaviors.add(element) ; } } } for (PackageImport pImport : p.getPackageImports()) { if (pImport.getVisibility() != VisibilityKind.PRIVATE_LITERAL) { importedBehaviors.addAll(processPublicallyImportedBehaviors(pImport.getImportedPackage())) ; } } return importedBehaviors ; } } protected class EnumerationLiteralNameStrategy implements AlfPartialScope.IGetNameStrategy { public String getName(EObject element) { if (element instanceof EnumerationLiteral) { return ((EnumerationLiteral)element).getName() ; } return "Unexpected element kind..." ; } } protected class EnumerationLiteralBuildScopeStrategy implements AlfPartialScope.IBuildScopeStrategy { public List<List<EObject>> buildScope(EObject contextElement) { List<List<EObject>> nestedScopes = new ArrayList<List<EObject>>() ; List<EObject> nestedList = new ArrayList<EObject>() ; if (!(contextElement instanceof Enumeration)) { nestedScopes.add(nestedList) ; return nestedScopes ; } Enumeration contextEnumeration = (Enumeration)contextElement ; // add all the literals owned by the context enumeration at the first scoping level nestedList.addAll(contextEnumeration.getOwnedLiterals()) ; nestedScopes.add(nestedList) ; // then builds other scoping levels based on context classifier inheritance hierarchy List<Classifier> currentGenerals = new ArrayList<Classifier>() ; currentGenerals.addAll(contextEnumeration.getGenerals()) ; List<Classifier> nextGenerals ; while (!currentGenerals.isEmpty()) { nextGenerals = new ArrayList<Classifier>() ; nestedList = new ArrayList<EObject>() ; for (Classifier general : currentGenerals) { nextGenerals.addAll(general.getGenerals()) ; if (general instanceof Enumeration) { for (EnumerationLiteral enumLiteral : ((Enumeration)general).getOwnedLiterals()) nestedList.add(enumLiteral) ; } } nestedScopes.add(nestedList) ; currentGenerals = nextGenerals ; } return nestedScopes ; } } public AlfPartialScope getVisibleEnumerationLiterals(EObject context) { AlfPartialScope.IGetNameStrategy nameStrategy = new EnumerationLiteralNameStrategy() ; AlfPartialScope.IBuildScopeStrategy buildScopeStrategy = new EnumerationLiteralBuildScopeStrategy() ; return new AlfPartialScope(nameStrategy, buildScopeStrategy, context) ; } }