| /******************************************************************************* |
| * Copyright (c) 2016 Uwe Ritzmann and others. |
| * |
| * 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: |
| * Uwe Ritzmann - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.m2m.internal.qvt.oml.runtime.resource; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.eclipse.emf.common.util.BasicEList; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.ecore.EAnnotation; |
| import org.eclipse.emf.ecore.EAttribute; |
| import org.eclipse.emf.ecore.EClass; |
| import org.eclipse.emf.ecore.EClassifier; |
| import org.eclipse.emf.ecore.EDataType; |
| import org.eclipse.emf.ecore.EEnumLiteral; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.EOperation; |
| import org.eclipse.emf.ecore.EPackage; |
| import org.eclipse.emf.ecore.EParameter; |
| import org.eclipse.emf.ecore.EReference; |
| import org.eclipse.emf.ecore.EStructuralFeature; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtEnvironmentBase; |
| import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtOperationalEnv; |
| import org.eclipse.m2m.internal.qvt.oml.ast.parser.IntermediateClassFactory; |
| import org.eclipse.m2m.internal.qvt.oml.ast.parser.QvtOperationalParserUtil; |
| import org.eclipse.m2m.internal.qvt.oml.cst.parser.QvtKeywords; |
| import org.eclipse.m2m.internal.qvt.oml.expressions.Constructor; |
| import org.eclipse.m2m.internal.qvt.oml.expressions.ConstructorBody; |
| import org.eclipse.m2m.internal.qvt.oml.expressions.ContextualProperty; |
| import org.eclipse.m2m.internal.qvt.oml.expressions.DirectionKind; |
| import org.eclipse.m2m.internal.qvt.oml.expressions.EntryOperation; |
| import org.eclipse.m2m.internal.qvt.oml.expressions.Helper; |
| import org.eclipse.m2m.internal.qvt.oml.expressions.ImperativeCallExp; |
| import org.eclipse.m2m.internal.qvt.oml.expressions.ImperativeOperation; |
| import org.eclipse.m2m.internal.qvt.oml.expressions.ImportKind; |
| import org.eclipse.m2m.internal.qvt.oml.expressions.Library; |
| import org.eclipse.m2m.internal.qvt.oml.expressions.MappingBody; |
| import org.eclipse.m2m.internal.qvt.oml.expressions.MappingCallExp; |
| import org.eclipse.m2m.internal.qvt.oml.expressions.MappingOperation; |
| import org.eclipse.m2m.internal.qvt.oml.expressions.MappingParameter; |
| import org.eclipse.m2m.internal.qvt.oml.expressions.ModelParameter; |
| import org.eclipse.m2m.internal.qvt.oml.expressions.ModelType; |
| import org.eclipse.m2m.internal.qvt.oml.expressions.Module; |
| import org.eclipse.m2m.internal.qvt.oml.expressions.ModuleImport; |
| import org.eclipse.m2m.internal.qvt.oml.expressions.ObjectExp; |
| import org.eclipse.m2m.internal.qvt.oml.expressions.OperationBody; |
| import org.eclipse.m2m.internal.qvt.oml.expressions.OperationalTransformation; |
| import org.eclipse.m2m.internal.qvt.oml.expressions.ResolveExp; |
| import org.eclipse.m2m.internal.qvt.oml.expressions.ResolveInExp; |
| import org.eclipse.m2m.internal.qvt.oml.expressions.VarParameter; |
| import org.eclipse.m2m.internal.qvt.oml.expressions.util.QVTOperationalVisitor; |
| import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.AltExp; |
| import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.AssertExp; |
| import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.AssignExp; |
| import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.BlockExp; |
| import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.BreakExp; |
| import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.CatchExp; |
| import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.ComputeExp; |
| import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.ContinueExp; |
| import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.DictLiteralExp; |
| import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.DictLiteralPart; |
| import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.DictionaryType; |
| import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.ForExp; |
| import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.ImperativeExpression; |
| import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.ImperativeIterateExp; |
| import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.ImperativeLoopExp; |
| import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.InstantiationExp; |
| import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.ListLiteralExp; |
| import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.ListType; |
| import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.LogExp; |
| import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.OrderedTupleLiteralExp; |
| import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.OrderedTupleLiteralPart; |
| import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.RaiseExp; |
| import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.ReturnExp; |
| import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.SeverityKind; |
| import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.SwitchExp; |
| import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.TryExp; |
| import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.UnlinkExp; |
| import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.UnpackExp; |
| import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.VariableInitExp; |
| import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.WhileExp; |
| import org.eclipse.ocl.ecore.AnyType; |
| import org.eclipse.ocl.ecore.BagType; |
| import org.eclipse.ocl.ecore.CallExp; |
| import org.eclipse.ocl.ecore.CallOperationAction; |
| import org.eclipse.ocl.ecore.CollectionType; |
| import org.eclipse.ocl.ecore.Constraint; |
| import org.eclipse.ocl.ecore.FeatureCallExp; |
| import org.eclipse.ocl.ecore.InvalidType; |
| import org.eclipse.ocl.ecore.LiteralExp; |
| import org.eclipse.ocl.ecore.LoopExp; |
| import org.eclipse.ocl.ecore.NavigationCallExp; |
| import org.eclipse.ocl.ecore.NumericLiteralExp; |
| import org.eclipse.ocl.ecore.OCLExpression; |
| import org.eclipse.ocl.ecore.OppositePropertyCallExp; |
| import org.eclipse.ocl.ecore.OrderedSetType; |
| import org.eclipse.ocl.ecore.PrimitiveLiteralExp; |
| import org.eclipse.ocl.ecore.PrimitiveType; |
| import org.eclipse.ocl.ecore.SendSignalAction; |
| import org.eclipse.ocl.ecore.SequenceType; |
| import org.eclipse.ocl.ecore.SetType; |
| import org.eclipse.ocl.ecore.TemplateParameterType; |
| import org.eclipse.ocl.ecore.TupleType; |
| import org.eclipse.ocl.ecore.TypeType; |
| import org.eclipse.ocl.ecore.VoidType; |
| import org.eclipse.ocl.expressions.AssociationClassCallExp; |
| import org.eclipse.ocl.expressions.BooleanLiteralExp; |
| import org.eclipse.ocl.expressions.CollectionItem; |
| import org.eclipse.ocl.expressions.CollectionKind; |
| import org.eclipse.ocl.expressions.CollectionLiteralExp; |
| import org.eclipse.ocl.expressions.CollectionLiteralPart; |
| import org.eclipse.ocl.expressions.CollectionRange; |
| import org.eclipse.ocl.expressions.EnumLiteralExp; |
| import org.eclipse.ocl.expressions.IfExp; |
| import org.eclipse.ocl.expressions.IntegerLiteralExp; |
| import org.eclipse.ocl.expressions.InvalidLiteralExp; |
| import org.eclipse.ocl.expressions.IterateExp; |
| import org.eclipse.ocl.expressions.IteratorExp; |
| import org.eclipse.ocl.expressions.LetExp; |
| import org.eclipse.ocl.expressions.MessageExp; |
| import org.eclipse.ocl.expressions.NullLiteralExp; |
| import org.eclipse.ocl.expressions.OperationCallExp; |
| import org.eclipse.ocl.expressions.PropertyCallExp; |
| import org.eclipse.ocl.expressions.RealLiteralExp; |
| import org.eclipse.ocl.expressions.StateExp; |
| import org.eclipse.ocl.expressions.StringLiteralExp; |
| import org.eclipse.ocl.expressions.TupleLiteralExp; |
| import org.eclipse.ocl.expressions.TupleLiteralPart; |
| import org.eclipse.ocl.expressions.TypeExp; |
| import org.eclipse.ocl.expressions.UnlimitedNaturalLiteralExp; |
| import org.eclipse.ocl.expressions.UnspecifiedValueExp; |
| import org.eclipse.ocl.expressions.Variable; |
| import org.eclipse.ocl.expressions.VariableExp; |
| import org.eclipse.ocl.utilities.ExpressionInOCL; |
| |
| public class UnparsingQVTOVisitor implements QVTOperationalVisitor<Object> |
| { |
| public void unparseModules(EList<Module> modules) |
| { |
| EList<ModuleImport> moduleImportList = getListOfModuleImports(modules); |
| unparseModuleImportsForCompilationUnit(moduleImportList); |
| |
| EList<ModelType> modelTypeList = getListOfModelTypes(modules); |
| unparseModelTypesForCompilationUnit(modelTypeList); |
| |
| for (Module module : modules) |
| { |
| unparseModule(module); |
| addEmptyLine(); |
| } |
| } |
| |
| private EList<ModuleImport> getListOfModuleImports(EList<Module> modules) |
| { |
| EList<ModuleImport> moduleImportList = new BasicEList<ModuleImport>(); |
| |
| for (Module module : modules) |
| { |
| for (ModuleImport moduleImport : module.getModuleImport()) |
| { |
| if (moduleImport == null || moduleImport.getImportedModule() == null) { |
| continue; |
| } |
| if (!modules.contains(moduleImport.getImportedModule())) |
| { |
| if (!moduleImportList.contains(moduleImport)) |
| { |
| moduleImportList.add(moduleImport); |
| } |
| } |
| } |
| } |
| |
| return moduleImportList; |
| } |
| |
| |
| public Object visitModule(Module module) |
| { |
| unparseModule(module); |
| return null; |
| } |
| |
| public void unparseModule(Module module) |
| { |
| if ( module instanceof OperationalTransformation ) |
| { |
| unparseOperationalTransformation((OperationalTransformation)module); |
| } |
| else if ( module instanceof Library ) |
| { |
| unparseLibrary((Library)module); |
| } |
| else |
| { |
| addText("/*___unknownModuleType___*/"); |
| } |
| } |
| |
| private void unparseOperationalTransformation(OperationalTransformation operationalTransformation) |
| { |
| unparseTags(operationalTransformation); |
| unparseOperationalTransformationSignature(operationalTransformation); |
| unparseModuleImportsForSignature(operationalTransformation); |
| addText("{"); |
| addLineBreak(); |
| unparseIntermediateClasses(operationalTransformation); |
| unparseModuleProperties(operationalTransformation); |
| unparseIntermediateProperties(operationalTransformation); |
| unparseModuleOperations(operationalTransformation); |
| addText("}"); |
| addLineBreak(); |
| } |
| |
| public Object visitLibrary(Library library) |
| { |
| unparseLibrary(library); |
| return null; |
| } |
| |
| private void unparseLibrary(Library library) |
| { |
| unparseTags(library); |
| unparseLibrarySignature(library); |
| unparseModuleImportsForSignature(library); |
| addText("{"); |
| addLineBreak(); |
| unparseModuleProperties(library); |
| unparseModuleOperations(library); |
| addText("}"); |
| addLineBreak(); |
| } |
| |
| private EList<ModelType> getListOfModelTypes(EList<Module> modules) |
| { |
| Set<String> handledMetamodels = new HashSet<String>(); |
| EList<ModelType> modelTypeList = new BasicEList<ModelType>(); |
| for (Module module : modules) |
| { |
| EList<ModelType> usedModelTypes = module.getUsedModelType(); |
| for (ModelType modelType : usedModelTypes) |
| { |
| String modelTypeKey = modelType.getName()+":"+modelType.getMetamodel().get(0).getNsURI(); |
| if ( !handledMetamodels.contains(modelTypeKey) ) |
| { |
| modelTypeList.add(modelType); |
| handledMetamodels.add(modelTypeKey); |
| } |
| } |
| } |
| return modelTypeList; |
| } |
| |
| private void unparseModelTypesForCompilationUnit(EList<ModelType> usedModelTypes) |
| { |
| for (ModelType modelType : usedModelTypes) |
| { |
| unparseModelType(modelType); |
| } |
| |
| if ( usedModelTypes.size() > 0 ) |
| addLineBreak(); |
| } |
| |
| public Object visitModelType(ModelType modelType) |
| { |
| unparseModelType(modelType); |
| return null; |
| } |
| |
| private void unparseModelType(ModelType modelType) |
| { |
| String instanceClassName = modelType.getInstanceClassName(); |
| if ( "org.eclipse.m2m.internal.qvt.oml.evaluator.ModelInstance".equals(instanceClassName) ) |
| { |
| String name = modelType.getName(); |
| String conformance = modelType.getConformanceKind(); |
| String conformanceText = conformance != null ? " \"" + conformance +"\"" : ""; |
| String nsURI = modelType.getMetamodel().get(0).getNsURI(); |
| addText("modeltype " + name + conformanceText + " uses \"" + nsURI + "\";"); |
| addLineBreak(); |
| modelTypeMap.put(modelType.getMetamodel().get(0),name); |
| } |
| else |
| { |
| addText("/*___unknownModelType___*/"); |
| addLineBreak(); |
| } |
| } |
| |
| private void unparseModuleImportsForCompilationUnit(EList<ModuleImport> moduleImportList) |
| { |
| for (ModuleImport moduleImport : moduleImportList) |
| { |
| Module importedModule = moduleImport.getImportedModule(); |
| |
| if ( importedModule instanceof Library ) |
| { |
| unparseLibraryImport((Library)importedModule); |
| |
| } |
| else if ( importedModule instanceof OperationalTransformation ) |
| { |
| unparseTransformationImport((OperationalTransformation)importedModule); |
| } |
| else |
| { |
| addText("/*___importOfUnknowModuleType___*/"); |
| addLineBreak(); |
| } |
| } |
| |
| if ( moduleImportList.size() > 0 ) |
| addLineBreak(); |
| } |
| |
| public Object visitModuleImport(ModuleImport moduleImport) |
| { |
| return null; |
| } |
| |
| private void unparseModuleImportsForSignature(Module module) |
| { |
| EList<ModuleImport> moduleImportList = module.getModuleImport(); |
| |
| for (ModuleImport moduleImport : moduleImportList) |
| { |
| unparseModuleImportForSignature(moduleImport); |
| addLineBreak(); |
| } |
| } |
| |
| private void unparseModuleImportForSignature(ModuleImport moduleImport) |
| { |
| ImportKind importKind = moduleImport.getKind(); |
| String kindToken = "imports"; |
| if ( ImportKind.ACCESS.equals(importKind) ) kindToken = "access"; |
| if ( ImportKind.EXTENSION.equals(importKind) ) kindToken = "extends"; |
| |
| Module importedModule = moduleImport.getImportedModule(); |
| |
| String libraryText = importedModule instanceof Library ? " library ": " "; |
| |
| String moduleName = importedModule.getName(); |
| moduleName = moduleName.replaceAll("\\.", "::"); |
| addText(kindToken + libraryText + moduleName); |
| |
| EList<ModelType> bindings = moduleImport.getBinding(); |
| if ( bindings != null && bindings.size() > 0 ) |
| { |
| addText("("); |
| for (Iterator<ModelType> modelTypeIterator = bindings.iterator(); modelTypeIterator.hasNext();) |
| { |
| addText(modelTypeIterator.next().getName()); |
| if ( modelTypeIterator.hasNext() ) |
| { |
| addText(", "); |
| } |
| } |
| addText(")"); |
| } |
| } |
| |
| private Set<String> importedLibraries = new HashSet<String>(); |
| |
| private void unparseLibraryImport(Library library) |
| { |
| String libraryName = library.getName(); |
| |
| Resource resource = library.eResource(); |
| String resourceURI = resource.getURI().toString(); |
| |
| if (resourceURI.startsWith("qvto://blackbox/")) |
| { |
| String unitName = resourceURI.replace("qvto://blackbox/", ""); |
| libraryName = unitName; |
| } |
| |
| if ( ! importedLibraries.contains(libraryName) ) |
| { |
| addText("import library " + libraryName + ";"); |
| addLineBreak(); |
| importedLibraries.add(libraryName); |
| } |
| |
| } |
| |
| private Set<String> importedTransformation = new HashSet<String>(); |
| |
| private void unparseTransformationImport(OperationalTransformation transformation) |
| { |
| String transformationName = transformation.getName(); |
| |
| Resource resource = transformation.eResource(); |
| String resourceURI = resource.getURI().toString(); |
| |
| if (resourceURI.startsWith("qvto://blackbox/")) |
| { |
| String unitName = resourceURI.replace("qvto://blackbox/", ""); |
| transformationName = unitName; |
| } |
| |
| if ( ! importedTransformation.contains(transformationName) ) |
| { |
| addText("import " + transformationName + ";"); |
| addLineBreak(); |
| importedTransformation.add(transformationName); |
| } |
| } |
| |
| private void unparseTags(Module module) |
| { |
| EList<EAnnotation> ownedTags = module.getOwnedTag(); |
| for ( EAnnotation eAnnotation : ownedTags ) |
| { |
| unparseTag(eAnnotation); |
| } |
| } |
| |
| private void unparseTag(EAnnotation annotation) |
| { |
| // <tag> ::= 'tag' <tagid> <scoped_identifier> ('=' <tagvalue>)? ';' |
| // <tagid> ::= <STRING> |
| // <tagvalue> :: <expression> |
| String tagidText = (String) annotation.getDetails().keySet().toArray()[0]; |
| if ( tagidText.equals(QvtOperationalEnv.TAG_ALIAS) ) |
| { |
| unparseAliasTag(annotation); |
| } |
| else |
| { |
| defaultUnparseTag(annotation); |
| } |
| } |
| |
| private void unparseAliasTag(EAnnotation annotation) |
| { |
| String tagidText = (String) annotation.getDetails().keySet().toArray()[0]; |
| String newNameText = (String) annotation.getDetails().values().toArray()[0]; |
| EObject referencedObject = annotation.getReferences().get(0); |
| if ( referencedObject instanceof EStructuralFeature ) |
| { |
| EStructuralFeature referencedFeature = (EStructuralFeature) referencedObject; |
| EClass referencedContainingClass = referencedFeature.getEContainingClass(); |
| String originalNameText = escapeKeywordName(referencedFeature.getName()); |
| String fqnText = constructFullyQualifiedType(referencedContainingClass); |
| addText("tag "); |
| addText("\"" + tagidText + "\" " + fqnText + "::" + originalNameText + " = '" + newNameText + "';"); |
| addLineBreak(); |
| } |
| } |
| |
| private void defaultUnparseTag(EAnnotation annotation) |
| { |
| String tagidText = (String) annotation.getDetails().keySet().toArray()[0]; |
| String valueText = (String) annotation.getDetails().values().toArray()[0]; |
| EObject referencedObject = annotation.getReferences().get(0); |
| if ( referencedObject instanceof EClassifier ) |
| { |
| EClassifier referencedClassifier = (EClassifier) referencedObject; |
| String fqnText = constructFullyQualifiedType(referencedClassifier); |
| addText("tag "); |
| addText("\"" + tagidText + "\" " + fqnText + " = '" + valueText + "';"); |
| addLineBreak(); |
| } |
| else if ( referencedObject instanceof EStructuralFeature ) |
| { |
| EStructuralFeature referencedFeature = (EStructuralFeature) referencedObject; |
| EClass referencedContainingClass = referencedFeature.getEContainingClass(); |
| String nameText = escapeKeywordName(referencedFeature.getName()); |
| String fqnClassText = constructFullyQualifiedType(referencedContainingClass); |
| addText("tag "); |
| addText("\"" + tagidText + "\" " + fqnClassText + "::" + nameText + " = '" + valueText + "';"); |
| addLineBreak(); |
| } |
| else |
| { |
| //TODO |
| } |
| } |
| |
| private void unparseType(EClassifier type) |
| { |
| if ( type != null ) |
| addText(constructFullyQualifiedType(type)); |
| } |
| |
| private void unparseHelperContext(VarParameter helperContext) |
| { |
| if ( helperContext != null ) |
| { |
| String contextString = constructFullyQualifiedType(helperContext.getType()); |
| addText(contextString + "::"); |
| } |
| } |
| |
| private Map<EPackage,String> modelTypeMap = new HashMap<EPackage,String>(); |
| |
| private String constructFullyQualifiedType(EClassifier type) |
| { |
| if ( type instanceof AnyType ) |
| return constructFullyQualifiedAnyType((AnyType)type); |
| if ( type instanceof EClass ) |
| return constructFullyQualifiedEClass((EClass)type); |
| if ( type instanceof EDataType ) |
| return constructFullyQualifiedEDataType((EDataType)type); |
| if ( type instanceof InvalidType ) |
| return constructFullyQualifiedInvalidType((InvalidType)type); |
| if ( type instanceof TemplateParameterType ) |
| return constructFullyQualifiedTemplateParameterType((TemplateParameterType)type); |
| if ( type instanceof TypeType ) |
| return constructFullyQualifiedTypeType((TypeType)type); |
| if ( type instanceof VoidType ) |
| return constructFullyQualifiedVoidType((VoidType)type); |
| return "/*___UnknownType___*/"; |
| } |
| |
| private String constructFullyQualifiedAnyType(AnyType type) |
| { |
| return "OclAny"; |
| } |
| |
| private String constructFullyQualifiedEClass(EClass type) |
| { |
| if ( type instanceof TupleType ) |
| return constructFullyQualifiedTupleType((TupleType)type); |
| |
| if ( IntermediateClassFactory.isIntermediateClass(type) ) |
| return constructFullyQualifiedIntermediateClass(type); |
| |
| return constructFullyQualifiedTypeAsPackagePrefixAndName(type); |
| } |
| |
| private String constructFullyQualifiedEDataType(EDataType type) |
| { |
| if ( type instanceof CollectionType ) |
| return constructFullyQualifiedCollectionType((CollectionType)type); |
| if ( type instanceof PrimitiveType ) |
| return constructFullyQualifiedPrimitiveType((PrimitiveType)type); |
| if ( type instanceof TupleType ) |
| return constructFullyQualifiedTupleType((TupleType)type); |
| |
| return constructFullyQualifiedTypeAsPackagePrefixAndName(type); |
| } |
| |
| private String constructFullyQualifiedCollectionType(CollectionType collectionType) |
| { |
| if ( collectionType instanceof DictionaryType ) |
| return constructFullyQualifiedDictionaryType((DictionaryType)collectionType); |
| |
| String collectionName = "Collection"; |
| if ( collectionType instanceof ListType ) |
| collectionName = "List"; |
| else if ( collectionType instanceof SequenceType ) |
| collectionName = "Sequence"; |
| else if ( collectionType instanceof OrderedSetType ) |
| collectionName = "OrderedSet"; |
| else if ( collectionType instanceof SetType ) |
| collectionName = "Set"; |
| else if ( collectionType instanceof BagType ) |
| collectionName = "Bag"; |
| |
| String elementTypeText = constructFullyQualifiedType(collectionType.getElementType()); |
| |
| return collectionName + "(" + elementTypeText + ")"; |
| } |
| |
| private String constructFullyQualifiedDictionaryType(DictionaryType dictionaryType) |
| { |
| String keyTypeText = constructFullyQualifiedType(dictionaryType.getKeyType()); |
| String elementTypeText = constructFullyQualifiedType(dictionaryType.getElementType()); |
| return "Dict(" + keyTypeText + "," + elementTypeText + ")"; |
| } |
| |
| private String constructFullyQualifiedPrimitiveType(PrimitiveType primitiveType) |
| { |
| return primitiveType.getName(); |
| } |
| |
| private String constructFullyQualifiedTupleType(TupleType tupleType) |
| { |
| StringBuffer featuresText = new StringBuffer(); |
| EList<EStructuralFeature> tupleFeatures = tupleType.getEStructuralFeatures(); |
| for (Iterator<EStructuralFeature> featureIterator = tupleFeatures.iterator(); featureIterator.hasNext();) |
| { |
| EStructuralFeature tupleFeature = featureIterator.next(); |
| String nameText = tupleFeature.getName(); |
| String fullTypeText = constructFullyQualifiedType(tupleFeature.getEType()); |
| featuresText.append(nameText + ":" + fullTypeText); |
| if ( featureIterator.hasNext() ) |
| featuresText.append(","); |
| } |
| return "Tuple(" + featuresText.toString() + ")"; |
| } |
| |
| private String constructFullyQualifiedInvalidType(InvalidType type) |
| { |
| return "OclInvalid"; |
| } |
| |
| private String constructFullyQualifiedTemplateParameterType(TemplateParameterType type) |
| { |
| return "/*___TemplateParameterType___*/";//TODO |
| } |
| |
| private String constructFullyQualifiedTypeType(TypeType type) |
| { |
| return "/*___TypeType___*/";//TODO |
| } |
| |
| private String constructFullyQualifiedVoidType(VoidType type) |
| { |
| return "OclVoid"; |
| } |
| |
| private String constructFullyQualifiedIntermediateClass(EClassifier intermediateClass) |
| { |
| return intermediateClass.getName(); |
| } |
| |
| private String constructFullyQualifiedTypeAsPackagePrefixAndName(EClassifier type) |
| { |
| String name = type.getName(); |
| String packagePrefix = constructPackagePrefix(type.getEPackage()); |
| |
| return packagePrefix + name; |
| } |
| |
| private String constructPackagePrefix(EPackage pakkage) |
| { |
| if ( pakkage instanceof Library ) |
| return constructPackagePrefixForLibrary((Library)pakkage); |
| |
| String packagePrefix = ""; |
| while (pakkage != null) |
| { |
| if (pakkage.getESuperPackage() != null) |
| { |
| packagePrefix = pakkage.getName() + "::" + packagePrefix; |
| pakkage = pakkage.getESuperPackage(); |
| } |
| else |
| { |
| String modelTypeName = modelTypeMap.get(pakkage); |
| if ( modelTypeName != null ) |
| { |
| packagePrefix = modelTypeName + "::" + packagePrefix; |
| } |
| pakkage = null; |
| } |
| } |
| return packagePrefix; |
| } |
| |
| private String constructPackagePrefixForLibrary(Library library) |
| { |
| String packagePrefix = library.getName() + "::"; |
| return packagePrefix; |
| } |
| |
| private String constructContextString(VarParameter context) |
| { |
| String contextString = context == null ? "" : constructFullyQualifiedType(context.getType()) + "::"; |
| return contextString; |
| } |
| |
| private void unparseOperationalTransformationSignature(OperationalTransformation transformation) |
| { |
| if ( transformation.isIsBlackbox() ) |
| { |
| addText("blackbox "); |
| } |
| |
| addText("transformation " + transformation.getName()); |
| |
| EList<ModelParameter> modelParameterList = removeAutogenParameter(transformation.getModelParameter()); |
| |
| addText("("); |
| for (Iterator<ModelParameter> modelParameterIterator = modelParameterList.iterator(); modelParameterIterator.hasNext();) |
| { |
| unparseTransformationParameter(modelParameterIterator.next()); |
| if ( modelParameterIterator.hasNext() ) |
| addText(", "); |
| } |
| addText(")"); |
| |
| addLineBreak(); |
| } |
| |
| private EList<ModelParameter> removeAutogenParameter(EList<ModelParameter> allModelParameter) |
| { |
| EList<ModelParameter> modelParameterList = new BasicEList<ModelParameter>(allModelParameter); |
| |
| for (int i = 0; i < modelParameterList.size(); ) |
| { |
| ModelParameter modelParameter = modelParameterList.get(i); |
| |
| EAnnotation annotation = modelParameter.getEAnnotation(QvtOperationalParserUtil.QVT_AUTOGEN_MODELPARAM_EXPRESSION_URI); |
| |
| if ( annotation != null ) |
| { |
| modelParameterList.remove(modelParameter); |
| } |
| else |
| { |
| i++; |
| } |
| } |
| return modelParameterList; |
| } |
| |
| private void unparseTransformationParameter(ModelParameter modelParameter) |
| { |
| String nameText = modelParameter.getName() + ":"; |
| if ( modelParameter.getName().startsWith(QvtOperationalEnv.GENERATED_NAME_SPECIAL_PREFIX) ) |
| { |
| nameText = "/*" + nameText + "*/"; |
| } |
| DirectionKind directionKind = modelParameter.getKind(); |
| String directionText = directionKind != null ? directionKind.getName() : "/*___directionKindWasNull___*/"; |
| EParameter representedParameter = modelParameter.getRepresentedParameter(); |
| String modelTypeText; |
| if ( representedParameter == null ) |
| { |
| ModelType modelType = (ModelType) modelParameter.getEType(); |
| modelTypeText = modelType != null ? modelType.getName() : "/*___modelTypeWasNull___*/"; |
| } |
| else |
| { |
| ModelType modelType = (ModelType) representedParameter.getEType(); |
| modelTypeText = modelType != null ? modelType.getName() : "/*___modelTypeOfRepresentedParameterWasNull___*/"; |
| } |
| addText(directionText + " " + nameText + modelTypeText); |
| } |
| |
| private void unparseIntermediateClasses(OperationalTransformation transformation) |
| { |
| EList<EClass> intermediateClasses = transformation.getIntermediateClass(); |
| for (Iterator<EClass> classIterator = intermediateClasses.iterator(); classIterator.hasNext();) |
| { |
| EClass eClass = classIterator.next(); |
| unparseIntermediateClassOrException(eClass); |
| } |
| } |
| |
| private void unparseIntermediateClassOrException(EClass clazz) |
| { |
| if ( clazz == null ) return; |
| |
| if ( !checkIntermediateException(clazz) ) |
| { |
| unparseIntermediateClass(clazz); |
| } |
| else |
| { |
| unparseIntermediateException(clazz); |
| } |
| } |
| |
| private boolean checkIntermediateException(EClass clazz) |
| { |
| if ( clazz == null ) return false; |
| |
| EList<EClass> superTypes = clazz.getESuperTypes(); |
| |
| if ( superTypes == null || superTypes.size() == 0 ) return false; |
| |
| for (Iterator<EClass> typesIterator = superTypes.iterator(); typesIterator.hasNext();) |
| { |
| EClass eClass = typesIterator.next(); |
| if (!eClass.getName().equals("Exception")) continue; |
| if (!eClass.getEPackage().getName().equals("Stdlib")) continue; |
| return true; |
| } |
| return false; |
| } |
| |
| private void unparseIntermediateClass(EClass clazz) |
| { |
| if ( clazz == null ) return; |
| |
| addText("intermediate class " + clazz.getName()); |
| |
| unparseIntermediateClassSupertypes(clazz.getESuperTypes()); |
| |
| addLineBreak(); |
| addTextAndIndent("{"); |
| addLineBreak(); |
| |
| unparseIntermediateClassProperties(clazz.getEAttributes()); |
| unparseIntermediateClassReferences(clazz.getEReferences()); |
| |
| unindentAndAddText("}"); |
| addEmptyLine(); |
| } |
| |
| private void unparseIntermediateException(EClass exceptionClass) |
| { |
| if ( exceptionClass == null ) return; |
| |
| addText("exception " + exceptionClass.getName()); |
| unparseIntermediateClassSupertypesWithoutExceptionClass(exceptionClass.getESuperTypes()); |
| addText(" {}"); |
| addLineBreak(); |
| } |
| |
| private void unparseIntermediateClassSupertypesWithoutExceptionClass(EList<EClass> superTypes) |
| { |
| EList<EClass> filteredSuperTypes = removeExceptionClassFromClassList(superTypes); |
| unparseIntermediateClassSupertypes(filteredSuperTypes); |
| } |
| |
| private EList<EClass> removeExceptionClassFromClassList(EList<EClass> superTypes) |
| { |
| EList<EClass> filteredClassList = new BasicEList<EClass>(); |
| for (Iterator<EClass> iterator = superTypes.iterator(); iterator.hasNext();) |
| { |
| EClass superType = iterator.next(); |
| if ( superType.getName().equals("Exception") && superType.getEPackage().getName().equals("Stdlib")) |
| { |
| //filter StdLib::Exception |
| } |
| else |
| { |
| filteredClassList.add(superType); |
| } |
| } |
| return filteredClassList; |
| } |
| |
| private void unparseIntermediateClassSupertypes(EList<EClass> superTypes) |
| { |
| if ( superTypes == null || superTypes.size() == 0 ) return; |
| |
| addText(" extends "); |
| |
| for (Iterator<EClass> typesIterator = superTypes.iterator(); typesIterator.hasNext();) |
| { |
| EClass eClass = typesIterator.next(); |
| unparseType(eClass); |
| if ( typesIterator.hasNext() ) |
| addText(", "); |
| } |
| } |
| |
| private void unparseIntermediateClassProperties(EList<EAttribute> properties) |
| { |
| if ( properties == null ) return; |
| |
| for (Iterator<EAttribute> propertyIterator = properties.iterator(); propertyIterator.hasNext();) |
| { |
| EAttribute property = propertyIterator.next(); |
| unparseIntermediateClassProperty(property); |
| } |
| } |
| |
| private void unparseIntermediateClassProperty(EAttribute property) |
| { |
| String assignmentOp = " = "; |
| |
| String idText = property.isID() ? "<<id>> " : ""; |
| |
| EAnnotation staticAnnotation = property.getEAnnotation(QvtOperationalParserUtil.QVT_NAMESPACE_URI + "/static"); |
| String staticText = staticAnnotation != null ? "static " : ""; |
| |
| String readonlyText = property.isChangeable() ? "" : "readonly "; |
| |
| String variableName = property.getName(); |
| |
| addText(idText + staticText + readonlyText + variableName + " : "); |
| unparseType(property.getEType()); |
| if ( property.isMany() ) |
| { |
| int lowerBound = property.getLowerBound(); |
| String lowerBoundText = (lowerBound != 0) ? String.valueOf(lowerBound) + " .. " : ""; |
| int upperBound = property.getUpperBound(); |
| String upperBoundText = (upperBound == -1 ) ? "*" : String.valueOf(upperBound); |
| addText("[" + lowerBoundText + upperBoundText + "]"); |
| } |
| else |
| { |
| if ( property.getLowerBound() == 1 ) |
| addText("[1]"); |
| } |
| if ( property.isOrdered() ) |
| addText(" ordered"); |
| |
| org.eclipse.ocl.expressions.OCLExpression<EClassifier> initExpression = QvtOperationalParserUtil.getInitExpression(property); |
| if ( initExpression != null ) |
| { |
| addText(assignmentOp); |
| unparseOCLExpression(initExpression); |
| } |
| addText(";"); |
| addLineBreak(); |
| } |
| |
| private void unparseIntermediateClassReferences(EList<EReference> references) |
| { |
| if ( references == null ) return; |
| |
| for (Iterator<EReference> referenceIterator = references.iterator(); referenceIterator.hasNext();) |
| { |
| EReference reference = referenceIterator.next(); |
| unparseIntermediateClassReference(reference); |
| } |
| } |
| |
| private void unparseIntermediateClassReference(EReference reference) |
| { |
| String assignmentOp = " = "; |
| |
| String variableName = reference.getName(); |
| |
| EAnnotation staticAnnotation = reference.getEAnnotation(QvtOperationalParserUtil.QVT_NAMESPACE_URI + "/static"); |
| String staticText = staticAnnotation != null ? "static " : ""; |
| |
| String readonlyText = reference.isChangeable() ? "" : "readonly "; |
| |
| if ( reference.isContainment() ) |
| { |
| addText("composes "); |
| } |
| else |
| { |
| addText("references "); |
| } |
| addText(staticText + readonlyText + variableName + " : "); |
| unparseType(reference.getEType()); |
| if ( reference.isMany() ) |
| addText("[*]"); |
| if ( reference.isOrdered() ) |
| addText(" ordered"); |
| |
| EReference opposite = reference.getEOpposite(); |
| if ( opposite != null ) |
| { |
| addText(" opposites " + opposite.getName()); |
| } |
| |
| org.eclipse.ocl.expressions.OCLExpression<EClassifier> initExpression = QvtOperationalParserUtil.getInitExpression(reference); |
| if ( initExpression != null ) |
| { |
| addText(assignmentOp); |
| unparseOCLExpression(initExpression); |
| } |
| addText(";"); |
| addLineBreak(); |
| } |
| |
| private void unparseLibrarySignature(Library library) |
| { |
| addText("library " + library.getName() + "("); |
| // for (Iterator<ETypeParameter> iterator = library.getETypeParameters().iterator(); iterator.hasNext();) |
| // { |
| // ETypeParameter typeParameter = iterator.next(); |
| // ModelType modelType = null;//FIXME visitLibrarySignature |
| // addText(modelType.getName()); |
| // if ( iterator.hasNext() ) |
| // { |
| // addText(", "); |
| // } |
| // } |
| addText(")"); |
| addLineBreak(); |
| } |
| |
| private void unparseModuleProperties(Module module) |
| { |
| EList<EStructuralFeature> configurationProperties = module.getConfigProperty(); |
| |
| EList<EStructuralFeature> properties = module.getEStructuralFeatures(); |
| |
| boolean hadProperty = false; |
| |
| for ( EStructuralFeature structuralFeature : properties ) |
| { |
| if ( structuralFeature instanceof EAttribute ) |
| { |
| EAttribute attribute = (EAttribute) structuralFeature; |
| unparseProperty(attribute,configurationProperties.contains(attribute)); |
| hadProperty = true; |
| } |
| else if ( structuralFeature instanceof EReference ) |
| { |
| EReference reference = (EReference) structuralFeature; |
| unparseProperty(reference,configurationProperties.contains(reference)); |
| hadProperty = true; |
| } |
| } |
| |
| if ( hadProperty ) |
| addLineBreak(); |
| } |
| |
| private void unparseProperty(EAttribute property, boolean isConfigurationProperty) |
| { |
| String propertyName = property.getName(); |
| addText((isConfigurationProperty ? "configuration " : "") + "property " + propertyName + ": "); |
| unparseType(property.getEType()); |
| |
| org.eclipse.ocl.expressions.OCLExpression<EClassifier> initExpression = QvtOperationalParserUtil.getInitExpression(property); |
| if ( initExpression != null ) |
| { |
| addText(" = "); |
| unparseOCLExpression(initExpression); |
| } |
| |
| addText(";"); |
| addLineBreak(); |
| } |
| |
| private void unparseProperty(EReference property, boolean isConfigurationProperty) |
| { |
| String propertyName = property.getName(); |
| addText((isConfigurationProperty ? "configuration " : "") + "property " + propertyName + ": "); |
| unparseType(property.getEType()); |
| |
| org.eclipse.ocl.expressions.OCLExpression<EClassifier> initExpression = QvtOperationalParserUtil.getInitExpression(property); |
| if ( initExpression != null ) |
| { |
| addText(" = "); |
| unparseOCLExpression(initExpression); |
| } |
| |
| addText(";"); |
| addLineBreak(); |
| } |
| |
| private void unparseIntermediateProperties(OperationalTransformation transformation) |
| { |
| EList<EStructuralFeature> intermediateProperties = transformation.getIntermediateProperty(); |
| |
| for ( EStructuralFeature property : intermediateProperties ) |
| { |
| unparseContextualProperty((ContextualProperty)property); |
| } |
| |
| if ( intermediateProperties.size()> 0 ) |
| addLineBreak(); |
| } |
| |
| private void unparseModuleOperations(Module module) |
| { |
| for ( EOperation operation : module.getEOperations() ) |
| { |
| if ( operation instanceof ImperativeOperation ) |
| { |
| unparseImperativeOperation((ImperativeOperation)operation); |
| } |
| else |
| { |
| addText("/*___notAnImperativeOperation:" + operation.getName() + "___*/"); |
| } |
| } |
| } |
| |
| public Object visitImperativeOperation(ImperativeOperation operation) |
| { |
| unparseImperativeOperation(operation); |
| return null; |
| } |
| |
| private void unparseImperativeOperation(ImperativeOperation operation) |
| { |
| if ( operation instanceof Constructor ) |
| { |
| unparseConstructor((Constructor)operation); |
| } |
| else if ( operation instanceof EntryOperation ) |
| { |
| unparseEntryOperation((EntryOperation)operation); |
| } |
| else if ( operation instanceof MappingOperation ) |
| { |
| unparseMappingOperation((MappingOperation)operation); |
| } |
| else if ( operation instanceof Helper ) |
| { |
| unparseHelper((Helper)operation); |
| } |
| else |
| { |
| addText("/*___unknownTypeOfImperativeOperationFor:" + operation.getName() + "___*/"); |
| } |
| } |
| |
| public Object visitConstructor(Constructor constructor) |
| { |
| unparseConstructor(constructor); |
| return null; |
| } |
| |
| private void unparseConstructor(Constructor constructor) |
| { |
| boolean isBlackbox = constructor.isIsBlackbox(); |
| if ( isBlackbox ) |
| { |
| addText("blackbox "); |
| } |
| addText("constructor "); |
| |
| unparseHelperContext(constructor.getContext()); |
| |
| addText(constructor.getName() + "("); |
| unparseMappingParameters(constructor.getEParameters()); |
| addText(")"); |
| |
| unparseVarParameters(constructor.getResult(),false); |
| |
| if ( isBlackbox ) |
| { |
| addText(";"); |
| addLineBreak(); |
| } |
| else |
| { |
| unparseConstructorBody((ConstructorBody)constructor.getBody()); |
| } |
| addEmptyLine(); |
| } |
| |
| public Object visitConstructorBody(ConstructorBody constructorBody) |
| { |
| unparseConstructorBody(constructorBody); |
| return null; |
| } |
| |
| private void unparseConstructorBody(ConstructorBody constructorBody) |
| { |
| if ( constructorBody == null ) |
| addText("/*___OperationBodyWasNull___*/"); |
| else |
| { |
| indent(); |
| unparseOCLExpressionsLinebreakSeparatedInBraces(constructorBody.getContent(),true); |
| unindent(); |
| } |
| } |
| |
| public Object visitEntryOperation(EntryOperation entryOperation) |
| { |
| unparseEntryOperation(entryOperation); |
| return null; |
| } |
| |
| private void unparseEntryOperation(EntryOperation entryOperation) |
| { |
| if ( entryOperation.getResult() != null && entryOperation.getResult().size() > 0 ) |
| { |
| addText("query "); |
| } |
| if ( entryOperation.getContext() != null ) |
| { |
| unparseVarParameter(entryOperation.getContext()); |
| } |
| addText(entryOperation.getName() + "("); |
| unparseMappingParameters(entryOperation.getEParameters()); |
| addText(")"); |
| unparseVarParameters(entryOperation.getResult(),true); |
| addLineBreak(); |
| unparseOperationBody(entryOperation.getBody()); |
| addLineBreak(); |
| } |
| |
| public Object visitOperationBody(OperationBody body) |
| { |
| unparseOperationBody(body); |
| return null; |
| } |
| |
| private void unparseOperationBody(OperationBody body) |
| { |
| if ( body != null ) |
| { |
| String sectionName = ""; |
| unparseBodySection(sectionName, body.getContent()); |
| } |
| else |
| { |
| addText("/*___OperationBodyWasNull___*/"); |
| } |
| } |
| |
| public Object visitMappingOperation(MappingOperation operation) |
| { |
| unparseMappingOperation(operation); |
| return null; |
| } |
| |
| |
| // |
| // Would be better if QvtOperationalParserUtil.isAbstarctOperation were public |
| // |
| static boolean isAbstractOperation(ImperativeOperation operation) { |
| EAnnotation annotation = operation.getEAnnotation(QvtOperationalParserUtil.QVT_NAMESPACE_URI); |
| if(annotation != null) { |
| String value = annotation.getDetails().get("abstract"/* QvtOperationalParserUtil.QVT_IS_ABSTRACT*/); |
| return Boolean.valueOf(value); |
| } |
| return false; |
| } |
| |
| |
| private void unparseMappingOperation(MappingOperation operation) |
| { |
| boolean isBlackbox = operation.isIsBlackbox(); |
| if ( isBlackbox ) |
| { |
| addText("blackbox "); |
| } |
| |
| boolean isAbstract = isAbstractOperation(operation); |
| if ( isAbstract ) |
| { |
| addText("abstract "); |
| } |
| // p.75: |
| // mapping inout <contexttype>::<mappingname> (<parameters>,) : <result-parameters> ... |
| |
| VarParameter context = operation.getContext(); |
| String directionKindText = ( context != null && DirectionKind.INOUT.equals(context.getKind())) ? "inout " : ""; |
| |
| addText("mapping " + directionKindText + getFullOperationName(operation) + "("); |
| unparseMappingParameters(operation.getEParameters()); |
| addText(")"); |
| |
| unparseMappingResultParameters(operation.getResult()); |
| addText(" "); |
| |
| unparseMappingExtensions(operation.getInherited(), operation.getMerged(), operation.getDisjunct()); |
| |
| // <mapping_refinement> ::= 'refines' <scoped_identifier> |
| if ( !isBlackbox ) |
| { |
| unparseMappingRefinement(operation.getOverridden()); |
| } |
| |
| unparseMappingConditions(operation.getWhen(), operation.getWhere()); |
| |
| if ( isBlackbox ) |
| { |
| addText(";"); |
| addLineBreak(); |
| } |
| else |
| { |
| boolean needsInit = checkMappingNeedsInit(operation); |
| unparseMappingBody((MappingBody)operation.getBody(),needsInit); |
| addEmptyLine(); |
| } |
| } |
| |
| private String getFullOperationName(ImperativeOperation operation) |
| { |
| String contextString = constructContextString(operation.getContext()); |
| String fullName = contextString + operation.getName(); |
| return fullName; |
| } |
| |
| private void unparseMappingResultParameters(EList<VarParameter> resultParameters) |
| { |
| if ( resultParameters == null || resultParameters.size() == 0 ) return; |
| |
| addText(" : "); |
| |
| boolean withName = resultParameters.size() != 1; |
| |
| for (Iterator<VarParameter> iterator = resultParameters.iterator(); iterator.hasNext();) |
| { |
| VarParameter parameter = iterator.next(); |
| unparseMappingParameter(parameter,false,withName); |
| if ( iterator.hasNext() ) |
| { |
| addText(", "); |
| } |
| } |
| } |
| |
| private void unparseMappingParameters(EList<EParameter> eParameters) |
| { |
| for (Iterator<EParameter> iterator = eParameters.iterator(); iterator.hasNext();) |
| { |
| EParameter parameter = iterator.next(); |
| unparseMappingParameter((VarParameter)parameter,true); |
| if ( iterator.hasNext() ) |
| { |
| addText(", "); |
| } |
| } |
| } |
| |
| private void unparseMappingParameter(VarParameter parameter, boolean withDirectionAndName) |
| { |
| unparseMappingParameter(parameter,withDirectionAndName,withDirectionAndName); |
| } |
| |
| private void unparseMappingParameter(VarParameter parameter, boolean withDirection, boolean withName) |
| { |
| String directionText = withDirection ? parameter.getKind().getLiteral() : ""; |
| String separatorText = withDirection && withName ? " " : ""; |
| String nameText = withName ? parameter.getName() : ""; |
| String semicolonText = withDirection || withName ? " : " : ""; |
| addText(directionText + separatorText + nameText + semicolonText); |
| unparseType(parameter.getType()); |
| if ( parameter instanceof MappingParameter ) |
| { |
| unparseExtentReference(((MappingParameter)parameter).getExtent()); |
| } |
| } |
| |
| private void unparseMappingExtensions(EList<MappingOperation> inherited, EList<MappingOperation> merged, EList<MappingOperation> disjunct) |
| { |
| // <mapping_extension> ::= <mapping_extension_key> <scoped_identifier_list> |
| // <mapping_extension_key> ::= 'inherits' | 'merges' | 'disjuncts' |
| unparseMappingExtension("inherits",inherited); |
| unparseMappingExtension("merges",merged); |
| unparseMappingExtension("disjuncts",disjunct); |
| } |
| |
| private void unparseMappingExtension(String relates, EList<MappingOperation> extendedOperations) |
| { |
| if ( extendedOperations != null && extendedOperations.size() > 0) |
| { |
| addLineBreak(); |
| addText(relates + " "); |
| for (Iterator<MappingOperation> operationIterator = extendedOperations.iterator(); operationIterator.hasNext();) |
| { |
| addText(getFullOperationName(operationIterator.next())); |
| if ( operationIterator.hasNext() ) |
| { |
| addText(","); |
| } |
| } |
| } |
| } |
| |
| private void unparseMappingRefinement(ImperativeOperation refinedOperation) |
| { |
| if ( refinedOperation != null ) |
| { |
| addLineBreak(); |
| addText("refines "); |
| addText(getFullOperationName(refinedOperation)); |
| addLineBreak(); |
| } |
| } |
| |
| private void unparseMappingConditions(EList<OCLExpression> when, OCLExpression where) |
| { |
| // when {<exprs>} where { <exprs>} |
| unparseMappingConditionList("when",when); |
| unparseMappingCondition("where",guaranteeBooleanExp(where)); |
| } |
| |
| private void unparseMappingConditionList(String preOrPost, EList<OCLExpression> condition) |
| { |
| if ( condition != null && condition.size() > 0 ) |
| { |
| addLineBreak(); |
| addText(preOrPost + " "); |
| unparseOCLExpressions("{ ",condition,"; "," }",false,false,false); |
| } |
| } |
| |
| private void unparseMappingCondition(String preOrPost, OCLExpression oclExpression) |
| { |
| if ( oclExpression != null ) |
| { |
| EList<OCLExpression> conditionList = new BasicEList<OCLExpression>(); |
| conditionList.add(oclExpression); |
| unparseMappingConditionList(preOrPost,conditionList); |
| } |
| } |
| |
| private OCLExpression guaranteeBooleanExp(OCLExpression expression) |
| { |
| if (expression instanceof BlockExp) |
| { |
| BlockExp block = (BlockExp) expression; |
| EList<OCLExpression> body = block.getBody(); |
| return body.get(0); |
| } |
| else |
| { |
| return expression; |
| } |
| } |
| |
| private boolean checkMappingNeedsInit(MappingOperation operation) |
| { |
| EList<EParameter> mappingParameters = operation.getEParameters(); |
| EList<VarParameter> mappingResults = operation.getResult(); |
| EList<VarParameter> outParameters = new BasicEList<VarParameter>(); |
| |
| for (Iterator<EParameter> iterator = mappingParameters.iterator(); iterator.hasNext();) |
| { |
| VarParameter mappingParameter = (VarParameter) iterator.next(); |
| DirectionKind directionKind = mappingParameter.getKind(); |
| if ( directionKind.equals(DirectionKind.INOUT) || directionKind.equals(DirectionKind.OUT) ) |
| outParameters.add(mappingParameter); |
| } |
| |
| outParameters.addAll(mappingResults); |
| |
| for (Iterator<VarParameter> iterator = outParameters.iterator(); iterator.hasNext();) |
| { |
| VarParameter varParameter = iterator.next(); |
| EClassifier parameterType = varParameter.getType(); |
| if ( parameterType instanceof EClass && ((EClass)parameterType).isAbstract() ) return true; |
| } |
| |
| return false; |
| } |
| |
| public Object visitMappingBody(MappingBody mappingBody) |
| { |
| unparseMappingBody(mappingBody,false); |
| return null; |
| } |
| |
| private void unparseMappingBody(MappingBody mappingBody, boolean needsInit) |
| { |
| boolean hasInit = mappingBody.getInitSection() != null && mappingBody.getInitSection().size() > 0; |
| boolean hasPopulation = mappingBody.getContent() != null && mappingBody.getContent().size() > 0; |
| boolean hasEnd = mappingBody.getEndSection() != null && mappingBody.getEndSection().size() > 0; |
| boolean hasBody = hasInit || hasPopulation || hasEnd; |
| if ( hasBody ) |
| { |
| addLineBreak(); |
| addTextAndIndent("{"); |
| addLineBreak(); |
| if ( hasInit || needsInit ) unparseBodySection("init",mappingBody.getInitSection()); |
| if ( hasPopulation ) unparsePopulationSection(mappingBody.getContent()); |
| if ( hasEnd ) unparseBodySection("end",mappingBody.getEndSection()); |
| unindentAndAddText("}"); |
| } |
| else |
| { |
| addText(";"); |
| } |
| } |
| |
| private void unparsePopulationSection(EList<OCLExpression> content) |
| { |
| if ( content == null || content.size() == 0 ) return; |
| |
| if ( content.size() == 1 && content.get(0) instanceof ObjectExp ) |
| { |
| ObjectExp objExp = (ObjectExp) content.get(0); |
| org.eclipse.ocl.ecore.Variable referredObject = objExp.getReferredObject(); |
| if ( referredObject != null ) |
| { |
| if ( referredObject.getName() == "result" ) |
| { |
| ConstructorBody constructorBody = objExp.getBody(); |
| if ( constructorBody == null ) |
| return; |
| else |
| { |
| unparseOCLExpressionsLinebreakSeparated(constructorBody.getContent(),true); |
| return; |
| } |
| }; |
| } |
| } |
| // default handling |
| unparseBodySection("population", content); |
| } |
| |
| public Object visitHelper(Helper helper) |
| { |
| unparseHelper(helper); |
| return null; |
| } |
| |
| private void unparseHelper(Helper helper) |
| { |
| boolean isBlackbox = helper.isIsBlackbox(); |
| |
| if ( isBlackbox ) |
| { |
| addText("blackbox "); |
| } |
| |
| String keyword = helper.isIsQuery() ? "query " : "helper "; |
| addText(keyword); |
| |
| unparseHelperContext(helper.getContext()); |
| addText(helper.getName() + "("); |
| unparseMappingParameters(helper.getEParameters()); |
| addText(")"); |
| |
| unparseVarParameters(helper.getResult(),true); |
| |
| if ( isBlackbox ) |
| { |
| addText(";"); |
| } |
| else |
| { |
| addLineBreak(); |
| unparseOperationBody(helper.getBody()); |
| } |
| addLineBreak(); |
| } |
| |
| private void unparseBodySection(String sectionName,EList<OCLExpression> content) |
| { |
| if ( sectionName != null && sectionName.length() > 0 ) |
| { |
| addText(sectionName); |
| addLineBreak(); |
| } |
| unparseOCLExpressionsLinebreakSeparatedInBraces(content,true); |
| addLineBreak(); |
| } |
| |
| private <T extends org.eclipse.ocl.expressions.OCLExpression<EClassifier>> |
| void unparseOCLExpressions(String head, EList<T> content, String separatorSuffix, String tail, boolean suffixAlways, boolean indented, boolean onSeperateLines) |
| { |
| if ( head != null ) |
| { |
| addText(head); |
| if ( onSeperateLines ) |
| addLineBreak(); |
| } |
| if ( indented ) |
| indent(); |
| for (Iterator<T> expressionIterator = content.iterator(); expressionIterator.hasNext();) |
| { |
| org.eclipse.ocl.expressions.OCLExpression<EClassifier> expression = expressionIterator.next(); |
| unparseOCLExpression(expression); |
| if (expressionIterator.hasNext() || suffixAlways) |
| addText(separatorSuffix); |
| if ( onSeperateLines ) |
| addLineBreak(); |
| } |
| if ( indented ) |
| unindent(); |
| if ( tail != null ) |
| { |
| addText(tail); |
| if ( onSeperateLines ) |
| addLineBreak(); |
| } |
| } |
| |
| private <T extends org.eclipse.ocl.expressions.OCLExpression<EClassifier>> void unparseOCLExpressionsCommaSeparatedInBrackets(EList<T> list) |
| { |
| unparseOCLExpressions("[", list, ",", "]", false, false, false); |
| } |
| |
| private <T extends org.eclipse.ocl.expressions.OCLExpression<EClassifier>> void unparseOCLExpressionsCommaSeparatedInParentheses(EList<T> list) |
| { |
| unparseOCLExpressions("(", list, ",", ")", false, false, false); |
| } |
| |
| private <T extends org.eclipse.ocl.expressions.OCLExpression<EClassifier>> void unparseOCLExpressionsSemicolonSeparatedInBraces(EList<T> list, boolean suffixAlways) |
| { |
| unparseOCLExpressions("{", list, ";", " }", suffixAlways, false, false); |
| } |
| |
| private <T extends org.eclipse.ocl.expressions.OCLExpression<EClassifier>> void unparseOCLExpressionsLinebreakSeparated(EList<T> list, boolean suffixAlways) |
| { |
| unparseOCLExpressions(null, list, ";", null, suffixAlways, false, true); |
| } |
| |
| private <T extends org.eclipse.ocl.expressions.OCLExpression<EClassifier>> void unparseOCLExpressionsLinebreakSeparatedInBraces(EList<T> list, boolean suffixAlways) |
| { |
| unparseOCLExpressions("{", list, ";", "}", suffixAlways, true, true); |
| } |
| |
| private <T extends org.eclipse.ocl.expressions.OCLExpression<EClassifier>> void unparseOCLExpression(T expression) |
| { |
| if ( expression == null ) return; |
| |
| if (expression instanceof CallExp) |
| { |
| unparseCallExpressions((CallExp)expression); |
| } |
| else if (expression instanceof org.eclipse.ocl.ecore.IfExp) |
| { |
| unparseIfExp((org.eclipse.ocl.ecore.IfExp)expression); |
| } |
| else if (expression instanceof ImperativeExpression) |
| { |
| unparseImperativeExpressions((ImperativeExpression)expression); |
| } |
| else if (expression instanceof org.eclipse.ocl.ecore.LetExp) |
| { |
| unparseLetExp((org.eclipse.ocl.ecore.LetExp)expression); |
| } |
| else if (expression instanceof LiteralExp) |
| { |
| unparseLiteralExpressions((org.eclipse.ocl.ecore.LiteralExp)expression); |
| } |
| else if (expression instanceof org.eclipse.ocl.ecore.MessageExp) |
| { |
| unparseMessageExp((org.eclipse.ocl.ecore.MessageExp)expression); |
| } |
| else if (expression instanceof org.eclipse.ocl.ecore.StateExp) |
| { |
| unparseStateExp((org.eclipse.ocl.ecore.StateExp)expression); |
| } |
| else if (expression instanceof org.eclipse.ocl.ecore.TypeExp) |
| { |
| unparseTypeExp((org.eclipse.ocl.ecore.TypeExp)expression); |
| } |
| else if (expression instanceof org.eclipse.ocl.ecore.UnspecifiedValueExp) |
| { |
| unparseUnspecifiedValueExp((org.eclipse.ocl.ecore.UnspecifiedValueExp)expression); |
| } |
| else if (expression instanceof org.eclipse.ocl.ecore.VariableExp) |
| { |
| unparseVariableExp((org.eclipse.ocl.ecore.VariableExp)expression); |
| } |
| else |
| { |
| addText("/*___unhandledOCLExpression:" + expression.getName() + "___*/"); |
| } |
| } |
| |
| private void unparseCallExpressions(CallExp expression) |
| { |
| if (expression instanceof FeatureCallExp) |
| { |
| unparseFeatureCallExpressions((FeatureCallExp)expression); |
| } |
| else if (expression instanceof LoopExp) |
| { |
| unparseLoopExpressions((LoopExp)expression); |
| } |
| else if (expression instanceof ResolveExp) |
| { |
| unparseResolveExpressions((ResolveExp)expression); |
| } |
| } |
| |
| private void unparseFeatureCallExpressions(FeatureCallExp expression) |
| { |
| if (expression instanceof NavigationCallExp) |
| { |
| unparseNavigationCallExpressions((NavigationCallExp)expression); |
| } |
| else if (expression instanceof org.eclipse.ocl.ecore.OperationCallExp) |
| { |
| unparseOperationCallExpressions((org.eclipse.ocl.ecore.OperationCallExp)expression); |
| } |
| } |
| |
| private void unparseNavigationCallExpressions(NavigationCallExp expression) |
| { |
| if (expression instanceof org.eclipse.ocl.ecore.AssociationClassCallExp) |
| { |
| unparseAssociationClassCallExp((org.eclipse.ocl.ecore.AssociationClassCallExp)expression); |
| } |
| else if (expression instanceof OppositePropertyCallExp) |
| { |
| unparseOppositePropertyCallExp((OppositePropertyCallExp)expression); |
| } |
| else if (expression instanceof org.eclipse.ocl.ecore.PropertyCallExp) |
| { |
| unparsePropertyCallExp((org.eclipse.ocl.ecore.PropertyCallExp)expression); |
| } |
| } |
| |
| public Object visitAssociationClassCallExp(AssociationClassCallExp<EClassifier, EStructuralFeature> call) |
| { |
| unparseAssociationClassCallExp(call); |
| return null; |
| } |
| |
| private void unparseAssociationClassCallExp(AssociationClassCallExp<EClassifier, EStructuralFeature> call) |
| { |
| unparseOCLExpression(call.getSource()); |
| addText("." + call.getNavigationSource().getName()); |
| unparseOCLExpressionsCommaSeparatedInBrackets(call.getQualifier()); |
| if ( call.isMarkedPre() ) |
| { |
| addText("@pre"); |
| } |
| } |
| |
| private void unparseOppositePropertyCallExp(OppositePropertyCallExp call) |
| { |
| unparseOCLExpression(call.getSource()); |
| addText("." + call.getReferredOppositeProperty().getName()); |
| unparseOCLExpressionsCommaSeparatedInBrackets(call.getQualifier()); |
| if ( call.isMarkedPre() ) |
| { |
| addText("@pre"); |
| } |
| } |
| |
| public Object visitPropertyCallExp(PropertyCallExp<EClassifier, EStructuralFeature> call) |
| { |
| unparsePropertyCallExp(call); |
| return null; |
| } |
| |
| private void unparsePropertyCallExp(PropertyCallExp<EClassifier, EStructuralFeature> call) |
| { |
| org.eclipse.ocl.expressions.OCLExpression<EClassifier> source = call.getSource(); |
| if ( |
| ( source instanceof VariableExp<?,?> ) && |
| ( variableNameIsGeneratedTemp(((VariableExp<?,?>)source).getReferredVariable().getName())) |
| ) |
| { |
| addText("/* " + ((VariableExp<?,?>)source).getReferredVariable().getName() + "*/"); |
| } |
| else |
| { |
| if ( source != null ) |
| { |
| if ( source instanceof VariableExp<?,?> ) |
| { |
| @SuppressWarnings("unchecked") |
| boolean namePrinted = unparseVariableExp((VariableExp<EClassifier,EParameter>)source); |
| if ( namePrinted ) |
| { |
| addText("."); |
| } |
| } |
| else |
| { |
| unparseOCLExpression(source); |
| addText("."); |
| } |
| } |
| else |
| { |
| addText("/*___sourceIsNull___*/"); |
| } |
| } |
| |
| |
| EStructuralFeature referredProperty = call.getReferredProperty(); |
| String propertyName = referredProperty.getName(); |
| String propertyText = escapeKeywordName(propertyName); |
| addText(propertyText); |
| |
| EList<org.eclipse.ocl.expressions.OCLExpression<EClassifier>> qualifier = call.getQualifier(); |
| if ( qualifier != null && qualifier.size() > 0 ) |
| unparseOCLExpressionsCommaSeparatedInBrackets(qualifier); |
| |
| if ( call.isMarkedPre() ) |
| { |
| addText("@pre"); |
| } |
| } |
| |
| private void unparseOperationCallExpressions(org.eclipse.ocl.ecore.OperationCallExp expression) |
| { |
| if (expression instanceof ImperativeCallExp) |
| { |
| unparseImperativeCallExpressions((ImperativeCallExp)expression); |
| } |
| else if (expression instanceof LogExp) |
| { |
| unparseLogExp((LogExp)expression); |
| } |
| else |
| { |
| unparseOperationCallExp(expression); |
| } |
| } |
| |
| private void unparseImperativeCallExpressions(ImperativeCallExp expression) |
| { |
| if (expression instanceof MappingCallExp) |
| { |
| unparseMappingCallExp((MappingCallExp)expression); |
| } |
| else |
| { |
| unparseImperativeCallExp(expression); |
| } |
| } |
| |
| public Object visitMappingCallExp(MappingCallExp expression) |
| { |
| unparseMappingCallExp(expression); |
| return null; |
| } |
| |
| private void unparseMappingCallExp(MappingCallExp expression) |
| { |
| unparseOperationCallExp(expression); |
| } |
| |
| private void unparseImperativeCallExp(ImperativeCallExp expression) |
| { |
| unparseOperationCallExp(expression); |
| } |
| |
| public Object visitLogExp(LogExp log) |
| { |
| unparseLogExp(log); |
| return null; |
| } |
| |
| private void unparseLogExp(LogExp log) |
| { |
| addText("log"); |
| unparseOCLExpressionsCommaSeparatedInParentheses(log.getArgument()); |
| OCLExpression condition = log.getCondition(); |
| if ( condition != null) |
| { |
| addText(" when "); |
| unparseOCLExpression(condition); |
| } |
| } |
| |
| public Object visitOperationCallExp(OperationCallExp<EClassifier, EOperation> expression) |
| { |
| unparseOperationCallExp(expression); |
| return null; |
| } |
| |
| private void unparseOperationCallExp(OperationCallExp<EClassifier, EOperation> expression) |
| { |
| org.eclipse.ocl.expressions.OCLExpression<EClassifier> source = expression.getSource(); |
| |
| String selector = ""; |
| boolean parenthesize = false; |
| if ( source != null ) |
| { |
| boolean sourceIsCollection = source.getType() instanceof CollectionType; |
| selector = sourceIsCollection ? "->" : "."; |
| |
| if ( source.getType() instanceof Library ) |
| selector = ""; |
| } |
| |
| EOperation referredOperation = expression.getReferredOperation(); |
| String operationName = referredOperation != null ? referredOperation.getName() : "/*___referredOperationWasNull___*/"; |
| |
| if ( expression instanceof MappingCallExp ) |
| { |
| String mappingCallText = ((MappingCallExp)expression).isIsStrict() ? "xmap " : "map "; |
| operationName = mappingCallText + operationName; |
| } |
| |
| if ( operationName.equals("=") || |
| operationName.equals("+") || |
| operationName.equals("-") || |
| operationName.equals("*") || |
| operationName.equals("/") || |
| operationName.equals("%") || |
| operationName.equals(">") || |
| operationName.equals("<") |
| ) |
| { |
| selector = ""; |
| parenthesize = true; |
| } |
| else if ( operationName.equals("<>") || operationName.equals("!=") ) |
| { |
| selector = ""; |
| operationName = " != "; |
| parenthesize = true; |
| } |
| else if ( operationName.equals("and") ) |
| { |
| selector = ""; |
| operationName = " and "; |
| parenthesize = true; |
| } |
| else if ( operationName.equals("or") ) |
| { |
| selector = ""; |
| operationName = " or "; |
| parenthesize = true; |
| } |
| |
| if ( parenthesize ) addText("("); |
| |
| EList<org.eclipse.ocl.expressions.OCLExpression<EClassifier>> argumentList = expression.getArgument(); |
| boolean hasArguments = argumentList != null & argumentList.size() > 0; |
| |
| if ( operationName.equals("-") && !hasArguments ) |
| { |
| //unary minus |
| addText(selector + operationName); |
| unparseOCLExpression((OCLExpression)source); |
| } |
| else |
| { |
| if ( source instanceof VariableExp ) |
| { |
| @SuppressWarnings("unchecked") |
| boolean isPrinted = unparseVariableExp((VariableExp<EClassifier, EParameter>)source); |
| selector = isPrinted ? selector : ""; |
| } |
| else |
| { |
| unparseOCLExpression((OCLExpression)source); |
| } |
| addText(selector + operationName); |
| unparseArgumentList(argumentList); |
| } |
| if ( parenthesize ) addText(")"); |
| } |
| |
| private <T extends org.eclipse.ocl.expressions.OCLExpression<EClassifier>> void unparseArgumentList(EList<T> argumentList) |
| { |
| addText("("); |
| for (Iterator<T> iterator = argumentList.iterator(); iterator.hasNext();) |
| { |
| org.eclipse.ocl.expressions.OCLExpression<EClassifier> argument = iterator.next(); |
| unparseOCLExpression((OCLExpression)argument); |
| if ( iterator.hasNext() ) |
| { |
| addText(", "); |
| } |
| } |
| addText(")"); |
| } |
| |
| private void unparseLoopExpressions(LoopExp expression) |
| { |
| if (expression instanceof ImperativeLoopExp) |
| { |
| unparseImperativeLoopExpressions((ImperativeLoopExp)expression); |
| } |
| else if (expression instanceof org.eclipse.ocl.ecore.IterateExp) |
| { |
| unparseIterateExp((org.eclipse.ocl.ecore.IterateExp)expression); |
| } |
| else if (expression instanceof org.eclipse.ocl.ecore.IteratorExp) |
| { |
| unparseIteratorExp((org.eclipse.ocl.ecore.IteratorExp)expression); |
| } |
| } |
| |
| private void unparseImperativeLoopExpressions(ImperativeLoopExp expression) |
| { |
| if (expression instanceof ForExp) |
| { |
| unparseForExp((ForExp)expression); |
| } |
| else if (expression instanceof ImperativeIterateExp) |
| { |
| unparseImperativeIterateExp((ImperativeIterateExp)expression); |
| } |
| } |
| |
| public Object visitForExp(ForExp expression) |
| { |
| unparseForExp(expression); |
| return null; |
| } |
| |
| private void unparseForExp(ForExp expression) |
| { |
| // p 105 |
| // <source>-><for-name> (<iterator-list> | <condition>) <body> ; |
| // <source>->< for-name> (<iterator-list> ) <body> ; |
| unparseOCLExpression((OCLExpression)expression.getSource()); |
| |
| addText("->" + expression.getName() + "("); |
| |
| unparseLoopExpIterator(expression.getIterator(),false); |
| |
| if ( expression.getCondition() != null ) |
| { |
| addText("|"); |
| unparseImperativeLoopExpCondition(expression.getCondition()); |
| } |
| addText(")"); |
| unparseBlockExpBody((OCLExpression)expression.getBody()); |
| } |
| |
| public Object visitImperativeIterateExp(ImperativeIterateExp expression) |
| { |
| unparseImperativeIterateExp(expression); |
| return null; |
| } |
| |
| private void unparseImperativeIterateExp(ImperativeIterateExp expression) |
| { |
| unparseOCLExpression((OCLExpression)expression.getSource()); |
| |
| addText("->" + expression.getName() + "("); |
| |
| unparseLoopExpIterator(expression.getIterator(),true); |
| |
| if ( expression.getTarget() != null ) |
| { |
| // <source> -> <collector-name> (<iterator-list>; <target> = <body> | <condition>) ; |
| addText(";"); |
| unparseVariable(expression.getTarget(),false); |
| addText("="); |
| unparseOCLExpression((OCLExpression)expression.getBody()); |
| addText("|"); |
| unparseImperativeLoopExpCondition(expression.getCondition()); |
| } |
| else |
| { |
| // <source> -> <collector-name> (<iterator-list> | <body_or_condition>) ; |
| // <source> -> <collector-name> (<body_or_condition>) ; |
| addText("|"); |
| unparseImperativeLoopExpBodyXorCondition(expression); |
| } |
| addText(")"); |
| } |
| |
| private void unparseLoopExpIterator(EList<Variable<EClassifier, EParameter>> loopIteratorList, boolean withType) |
| { |
| if ( loopIteratorList != null && loopIteratorList.size() > 0 ) |
| { |
| for (Iterator<Variable<EClassifier, EParameter>> iterator = loopIteratorList.iterator(); iterator.hasNext();) |
| { |
| Variable<EClassifier, EParameter> loopIterator = |
| (Variable<EClassifier, EParameter>) iterator.next(); |
| unparseVariableNameType(loopIterator,withType); |
| if ( iterator.hasNext() ) |
| addText(","); |
| } |
| } |
| } |
| |
| private void unparseImperativeLoopExpBodyXorCondition(ImperativeLoopExp expression) |
| { |
| if ( expression.getBody() != null && expression.getCondition() == null ) |
| { |
| unparseLoopExpBody((OCLExpression)expression.getBody()); |
| } |
| else if ( expression.getBody() == null && expression.getCondition() != null ) |
| { |
| unparseImperativeLoopExpCondition(expression.getCondition()); |
| } |
| else |
| { |
| addText("/*body:"+expression.getBody() + "; condition:" + expression.getCondition() + "*/"); |
| } |
| } |
| |
| private void unparseLoopExpBody(OCLExpression body) |
| { |
| unparseOCLExpression(body); |
| } |
| |
| private void unparseImperativeLoopExpCondition(OCLExpression condition) |
| { |
| if ( condition instanceof org.eclipse.ocl.ecore.TypeExp ) |
| { |
| unparseTypeExp((org.eclipse.ocl.ecore.TypeExp) condition); |
| } |
| else |
| { |
| unparseOCLExpression(condition); |
| } |
| } |
| |
| public Object visitIterateExp(IterateExp<EClassifier, EParameter> iterateExp) |
| { |
| unparseIterateExp(iterateExp); |
| return null; |
| } |
| |
| private void unparseIterateExp(IterateExp<EClassifier, EParameter> iterateExp) |
| { |
| // <iterate_exp> ::= 'iterate' '(' <declarator_list> ';' <declarator> '|' <expression> ')' |
| |
| unparseOCLExpression((OCLExpression)iterateExp.getSource()); |
| addText("->" + "iterate" + "("); |
| unparseVariablesCommaSeparated(iterateExp.getIterator()); |
| addText(";"); |
| unparseVariable(iterateExp.getResult(),true); |
| addText("|"); |
| unparseOCLExpression(iterateExp.getBody()); |
| addText(")"); |
| } |
| |
| public Object visitIteratorExp(IteratorExp<EClassifier, EParameter> expression) |
| { |
| unparseIteratorExp(expression); |
| return null; |
| } |
| |
| private void unparseIteratorExp(IteratorExp<EClassifier, EParameter> expression) |
| { |
| unparseOCLExpression((OCLExpression)expression.getSource()); |
| addText("->" + expression.getName() + "("); |
| unparseLoopExpIterator(expression.getIterator(),true); |
| addText("|"); |
| unparseLoopExpBody((OCLExpression)expression.getBody()); |
| addText(")"); |
| } |
| |
| private void unparseResolveExpressions(ResolveExp expression) |
| { |
| if (expression instanceof ResolveInExp) |
| { |
| unparseResolveInExp((ResolveInExp)expression); |
| } |
| else |
| { |
| unparseResolveExp((ResolveExp)expression); |
| } |
| } |
| |
| public Object visitResolveExp(ResolveExp expression) |
| { |
| unparseResolveExp(expression); |
| return null; |
| } |
| |
| public Object visitResolveInExp(ResolveInExp expression) |
| { |
| unparseResolveInExp(expression); |
| return null; |
| } |
| |
| private void unparseResolveExp(ResolveExp expression) |
| { |
| // <resolve_exp> ::= <resolve_key> '(' <resolve_condition>? ')' |
| // <resolve_key> ::= 'late'? <resolve_kind> |
| // <resolve_kind> ::= 'resolve' | 'resolveone' | 'invresolve' | 'invresolveone' |
| // <resolve_condition> ::= <declarator> ('|' <expression>)? |
| unparseSource(expression.getSource()); |
| |
| String resolveKindText = constructResolveKindText(expression); |
| addText(resolveKindText +"("); |
| |
| org.eclipse.ocl.ecore.Variable target = expression.getTarget(); |
| if ( target != null ) |
| { |
| boolean hasCondition = expression.getCondition() != null; |
| String targetNameText = hasCondition ? target.getName() + " : " : ""; |
| addText(targetNameText); |
| unparseType(target.getType()); |
| } |
| |
| unparseResolveExpCondition(expression.getCondition()); |
| |
| addText(")"); |
| } |
| |
| private void unparseResolveInExp(ResolveInExp expression) |
| { |
| // <resolve_in_exp> ::= <resolve_in_key> '(' <scoped_identifier> (',' <resolve_condition>)?')' |
| // <resolve_in_key> ::= 'late'? <resolve_in_kind> |
| // <resolve_in_kind> ::= 'resolveIn' | 'resolveoneIn' | 'invresolveIn' | 'invresolveoneIn' |
| // <resolve_condition> ::= <declarator> ('|' <expression>)? |
| unparseSource(expression.getSource()); |
| String resolveInKindText = constructResolveKindText(expression); |
| resolveInKindText += "In"; |
| addText(resolveInKindText +"("); |
| |
| MappingOperation inMapping = expression.getInMapping(); |
| String inMappingText = inMapping != null ? getFullOperationName(inMapping) : "/*___InMappingWasNull___*/"; |
| addText(inMappingText); |
| |
| org.eclipse.ocl.ecore.Variable target = expression.getTarget(); |
| if ( target != null ) |
| { |
| boolean hasCondition = expression.getCondition() != null; |
| String targetNameText = hasCondition ? target.getName() + " : " : ""; |
| addText(", " + targetNameText); |
| unparseType(target.getType()); |
| } |
| |
| unparseResolveExpCondition(expression.getCondition()); |
| |
| addText(")"); |
| } |
| |
| private void unparseSource(org.eclipse.ocl.expressions.OCLExpression<EClassifier> source) |
| { |
| if ( source != null ) |
| { |
| if ( source instanceof VariableExp ) |
| { |
| @SuppressWarnings("unchecked") |
| boolean isPrinted = unparseVariableExp((VariableExp<EClassifier, EParameter>)source); |
| addText(isPrinted ? "." : ""); |
| } |
| else |
| { |
| unparseOCLExpression((OCLExpression)source); |
| addText("."); |
| } |
| } |
| } |
| |
| private String constructResolveKindText(ResolveExp expression) |
| { |
| String resolveInKindText = "resolve"; |
| resolveInKindText = expression.isIsInverse() ? "inv" + resolveInKindText : resolveInKindText; |
| resolveInKindText += expression.isOne() ? "one" : ""; |
| resolveInKindText = expression.isIsDeferred() ? ("late " + resolveInKindText) : resolveInKindText; |
| return resolveInKindText; |
| } |
| |
| private void unparseResolveExpCondition(OCLExpression resolveCondition) |
| { |
| if ( resolveCondition != null ) |
| { |
| addText(" | "); |
| unparseImperativeLoopExpCondition(resolveCondition); |
| } |
| } |
| |
| public Object visitIfExp(IfExp<EClassifier> expression) |
| { |
| unparseIfExp(expression); |
| return null; |
| } |
| |
| private void unparseIfExp(IfExp<EClassifier> expression) |
| { |
| // <if_exp> ::= 'if' <expression> <then_part> |
| // <elif_part>* <else_part>? 'endif' |
| // <then_part> ::= 'then' <if_body> |
| // <elif_part> ::= 'elif' <if_body> |
| // <else_part> ::= 'else' <if_body> |
| // <if_body> ::= <expression> | <expression_block> |
| addText("if ("); |
| unparseOCLExpression((OCLExpression)expression.getCondition()); |
| addText(")"); |
| indent(); |
| addLineBreak(); |
| addTextAndIndent("then "); |
| unparseOCLExpression((OCLExpression)expression.getThenExpression()); |
| if ( expression.getElseExpression() != null ) |
| { |
| addLineBreak(); |
| unindentAndAddText("else "); |
| indent(); |
| unparseOCLExpression((OCLExpression)expression.getElseExpression()); |
| } |
| addLineBreak(); |
| unindentAndAddText("endif "); |
| unindent(); |
| } |
| |
| private void unparseImperativeExpressions(ImperativeExpression expression) |
| { |
| if (expression instanceof AltExp) |
| { |
| unparseAltExp((AltExp) expression); |
| } |
| else if (expression instanceof AssertExp) |
| { |
| unparseAssertExp((AssertExp) expression); |
| } |
| else if (expression instanceof AssignExp) |
| { |
| unparseAssignExp((AssignExp) expression); |
| } |
| else if (expression instanceof BlockExp) |
| { |
| unparseBlockExp((BlockExp) expression, true, false); |
| } |
| else if (expression instanceof BreakExp) |
| { |
| unparseBreakExp((BreakExp) expression); |
| } |
| else if (expression instanceof CatchExp) |
| { |
| unparseCatchExp((CatchExp) expression); |
| } |
| else if (expression instanceof ComputeExp) |
| { |
| unparseComputeExp((ComputeExp) expression); |
| } |
| else if (expression instanceof ContinueExp) |
| { |
| unparseContinueExp((ContinueExp) expression); |
| } |
| else if (expression instanceof InstantiationExp) |
| { |
| unparseInstantiationExpressions((InstantiationExp) expression); |
| } |
| else if (expression instanceof RaiseExp) |
| { |
| unparseRaiseExp((RaiseExp) expression); |
| } |
| else if (expression instanceof ReturnExp) |
| { |
| unparseReturnExp((ReturnExp) expression); |
| } |
| else if (expression instanceof SwitchExp) |
| { |
| unparseSwitchExp((SwitchExp) expression); |
| } |
| else if (expression instanceof TryExp) |
| { |
| unparseTryExp((TryExp) expression); |
| } |
| else if (expression instanceof UnlinkExp) |
| { |
| unparseUnlinkExp((UnlinkExp) expression); |
| } |
| else if (expression instanceof UnpackExp) |
| { |
| unparseUnpackExp((UnpackExp) expression); |
| } |
| else if (expression instanceof VariableInitExp) |
| { |
| unparseVariableInitExp((VariableInitExp) expression); |
| } |
| else if (expression instanceof WhileExp) |
| { |
| unparseWhileExp((WhileExp) expression); |
| } |
| } |
| |
| public Object visitAltExp(AltExp astNode) |
| { |
| unparseAltExp(astNode); |
| return null; |
| } |
| |
| private void unparseAltExp(AltExp astNode) |
| { |
| addText("AltExp"); |
| } |
| |
| public Object visitAssertExp(AssertExp assertExpression) |
| { |
| unparseAssertExp(assertExpression); |
| return null; |
| } |
| |
| private void unparseAssertExp(AssertExp assertExpression) |
| { |
| addText("assert "); |
| |
| SeverityKind severity = assertExpression.getSeverity(); |
| if ( severity != null ) |
| addText(severity.getLiteral() + " "); |
| |
| addText("("); |
| unparseOCLExpression(assertExpression.getAssertion()); |
| addText(")"); |
| |
| LogExp logExpression = assertExpression.getLog(); |
| if ( logExpression != null ) |
| { |
| addText(" with "); |
| unparseLogExp(logExpression); |
| } |
| } |
| |
| public Object visitAssignExp(AssignExp assignment) |
| { |
| unparseAssignExp(assignment); |
| return null; |
| } |
| |
| private void unparseAssignExp(AssignExp assignment) |
| { |
| unparseOCLExpression(assignment.getLeft()); |
| |
| String operatorText = assignment.isIsReset() ? " := " : " += "; |
| addText(operatorText); |
| |
| if ( assignment.getValue().size() == 1 ) |
| { |
| unparseOCLExpression(assignment.getValue().get(0)); |
| } |
| else |
| { |
| unparseOCLExpressionsSemicolonSeparatedInBraces(assignment.getValue(), false); |
| } |
| } |
| |
| public Object visitBlockExp(BlockExp block) |
| { |
| unparseBlockExp(block,true,false); |
| return null; |
| } |
| |
| private void unparseBlockExp(BlockExp block, boolean printDo, boolean suffixAlways) |
| { |
| if ( printDo ) |
| addText("do "); |
| unparseOCLExpressionsSemicolonSeparatedInBraces(block.getBody(),suffixAlways); |
| } |
| |
| public Object visitBreakExp(BreakExp expression) |
| { |
| unparseBreakExp(expression); |
| return null; |
| } |
| |
| private void unparseBreakExp(BreakExp expression) |
| { |
| addText("break"); |
| } |
| |
| public Object visitCatchtExp(CatchExp expression) |
| { |
| unparseCatchExp(expression); |
| return null; |
| } |
| |
| private void unparseCatchExpressions(EList<CatchExp> catchExpressions) |
| { |
| for (Iterator<CatchExp> iterator = catchExpressions.iterator(); iterator.hasNext();) |
| { |
| CatchExp catchExpression = iterator.next(); |
| unparseCatchExp(catchExpression); |
| } |
| } |
| |
| private void unparseCatchExp(CatchExp expression) |
| { |
| addText("except ("); |
| |
| EAnnotation catchVarAnnotation = expression.getEAnnotation(QvtOperationalParserUtil.QVT_NAMESPACE_URI + "/catchVar"); |
| if ( catchVarAnnotation != null ) |
| { |
| unparseCatchVarAnnotation(catchVarAnnotation); |
| } |
| |
| unparseCatchExpExceptions(expression.getException()); |
| |
| addText(") "); |
| unparseTryBody(expression.getBody()); |
| } |
| |
| private void unparseCatchVarAnnotation(EAnnotation catchVarAnnotation) |
| { |
| EList<EObject> contents = catchVarAnnotation.getContents(); |
| |
| if ( contents != null && contents.size() > 0 ) |
| { |
| EObject exceptionObject = contents.get(0); |
| |
| if ( exceptionObject instanceof Variable<?,?> ) |
| { |
| @SuppressWarnings("unchecked") |
| Variable<EClassifier,EObject> catchVariable = (Variable<EClassifier,EObject>) exceptionObject; |
| addText(catchVariable.getName() + ":"); |
| } |
| } |
| } |
| |
| private void unparseCatchExpExceptions(EList<EClassifier> exceptions) |
| { |
| if ( exceptions == null ) return; |
| |
| for (Iterator<EClassifier> iterator = exceptions.iterator(); iterator.hasNext();) |
| { |
| EClassifier exception = iterator.next(); |
| |
| addText(exception.getName()); |
| if ( iterator.hasNext() ) |
| { |
| addText(","); |
| } |
| } |
| } |
| |
| public Object visitComputeExp(ComputeExp expression) |
| { |
| unparseComputeExp(expression); |
| return null; |
| } |
| |
| private void unparseComputeExp(ComputeExp expression) |
| { |
| org.eclipse.ocl.ecore.Variable variable = expression.getReturnedElement(); |
| OCLExpression body = expression.getBody(); |
| |
| if ( body instanceof WhileExp ) |
| { |
| WhileExp whileExp = (WhileExp) body; |
| addText("while ("); |
| unparseVariable(variable,true); |
| addText(";"); |
| unparseOCLExpression(whileExp.getCondition()); |
| addText(")"); |
| unparseBlockExpBody(whileExp.getBody()); |
| } |
| else |
| { |
| addText("compute ("); |
| unparseVariable(variable,true); |
| addText(")"); |
| unparseBlockExpBody(body); |
| } |
| } |
| |
| public Object visitContinueExp(ContinueExp expression) |
| { |
| unparseContinueExp(expression); |
| return null; |
| } |
| |
| private void unparseContinueExp(ContinueExp expression) |
| { |
| addText("continue"); |
| } |
| |
| private void unparseInstantiationExpressions(InstantiationExp expression) |
| { |
| if (expression instanceof ObjectExp) |
| { |
| unparseObjectExp((ObjectExp)expression); |
| } |
| else |
| { |
| unparseInstantiationExp(expression); |
| } |
| } |
| |
| public Object visitObjectExp(ObjectExp expression) |
| { |
| unparseObjectExp(expression); |
| return null; |
| } |
| |
| private void unparseObjectExp(ObjectExp expression) |
| { |
| addText("object "); |
| if ( expression.getReferredObject() != null ) |
| { |
| unparseVariableNameType(expression.getReferredObject()); |
| } |
| unparseExtentReference(expression.getExtent()); |
| addText(" "); |
| unparseConstructorBody(expression.getBody()); |
| } |
| |
| private void unparseExtentReference(org.eclipse.ocl.ecore.Variable extent) |
| { |
| if ( extent != null ) |
| { |
| if ( ! extent.getName().startsWith(QvtOperationalEnv.GENERATED_NAME_SPECIAL_PREFIX) ) |
| { |
| addText("@" + extent.getName()); |
| } |
| } |
| } |
| |
| public Object visitInstantiationExp(InstantiationExp expression) |
| { |
| unparseInstantiationExp(expression); |
| return null; |
| } |
| |
| private void unparseInstantiationExp(InstantiationExp expression) |
| { |
| addText("new "); |
| unparseType(expression.getType()); |
| unparseExtentReference(expression.getExtent()); |
| unparseArgumentList(expression.getArgument()); |
| } |
| |
| public Object visitRaiseExp(RaiseExp raise) |
| { |
| unparseRaiseExp(raise); |
| return null; |
| } |
| |
| private void unparseRaiseExp(RaiseExp raise) |
| { |
| // <raise_exp> ::= 'raise' <scoped_identifier> ('(' <arg_list>? ')')? |
| // <arg_list> ::= <expression_comma_list> |
| raise.getArgument(); |
| raise.getException(); |
| addText("raise "); |
| unparseType(raise.getException()); |
| if ( raise.getArgument() != null ) |
| { |
| addText("("); |
| unparseOCLExpression(raise.getArgument()); |
| addText(")"); |
| } |
| } |
| |
| public Object visitReturnExp(ReturnExp expression) |
| { |
| unparseReturnExp(expression); |
| return null; |
| } |
| |
| private void unparseReturnExp(ReturnExp expression) |
| { |
| //<return_exp> ::= 'return' <expression>? |
| |
| addText("return"); |
| if ( expression.getValue() != null ) |
| { |
| addText(" "); |
| unparseOCLExpression(expression.getValue()); |
| } |
| } |
| |
| public Object visitSwitchExp(SwitchExp svvitch) |
| { |
| unparseSwitchExp(svvitch); |
| return null; |
| } |
| |
| private void unparseSwitchExp(SwitchExp svvitch) |
| { |
| // <switch_exp> ::= 'switch' ('(' <iter_declarator> ')')? <switch_body> |
| // <switch_body> ::= '{' <switch_alt>+ <switch_else>? '}' |
| // <switch_alt> ::= 'case' '(' <expression> ')' <expression_statement> |
| // <switch_else> ::= 'else' <expression_statement> |
| svvitch.getElsePart(); |
| |
| addTextAndIndent("switch {"); |
| addLineBreak(); |
| EList<AltExp> altExpList = svvitch.getAlternativePart(); |
| for (AltExp altExp : altExpList) |
| { |
| addText("case ("); |
| unparseOCLExpression(altExp.getCondition()); |
| addText(") "); |
| unparseOCLExpression(altExp.getBody()); |
| addText(";"); |
| addLineBreak(); |
| } |
| if ( svvitch.getElsePart() != null ) |
| { |
| addText("else "); |
| unparseOCLExpression(svvitch.getElsePart()); |
| addText(";"); |
| addLineBreak(); |
| } |
| unindentAndAddText("}"); |
| } |
| |
| public Object visitTryExp(TryExp expression) |
| { |
| unparseTryExp(expression); |
| return null; |
| } |
| |
| private void unparseTryExp(TryExp expression) |
| { |
| addText("try "); |
| EList<OCLExpression> tryBody = expression.getTryBody(); |
| unparseTryBody(tryBody); |
| unparseCatchExpressions(expression.getExceptClause()); |
| } |
| |
| private void unparseTryBody(EList<OCLExpression> tryBody) |
| { |
| EList<OCLExpression> unparseBody = tryBody; |
| |
| if ( unparseBody.size() == 1 && unparseBody.get(0) instanceof BlockExp ) |
| { |
| BlockExp block = (BlockExp) unparseBody.get(0); |
| unparseBody = block.getBody(); |
| } |
| |
| unparseOCLExpressionsLinebreakSeparatedInBraces(unparseBody,true); |
| addLineBreak(); |
| } |
| |
| public Object visitUnlinkExp(UnlinkExp unlink) |
| { |
| unparseUnlinkExp(unlink); |
| return null; |
| } |
| |
| private void unparseUnlinkExp(UnlinkExp unlink) |
| { |
| unparseOCLExpression(unlink.getTarget()); |
| addText(".unlink("); |
| unparseOCLExpression(unlink.getItem()); |
| addText(")"); |
| } |
| |
| public Object visitUnpackExp(UnpackExp unpack) |
| { |
| unparseUnpackExp(unpack); |
| return null; |
| } |
| |
| private void unparseUnpackExp(UnpackExp unpack) |
| { |
| addText("var "); |
| unparseOCLVariablesCommaSeparated(unpack.getTargetVariable()); |
| addText(" := "); |
| unparseOCLExpression(unpack.getSource()); |
| } |
| |
| private void unparseOCLVariablesCommaSeparated(EList<org.eclipse.ocl.ecore.Variable> list) |
| { |
| unparseOCLVariables("","",list,",",""); |
| } |
| |
| private void unparseOCLVariables(String head, String prefix, EList<org.eclipse.ocl.ecore.Variable> list, String separatorSuffix, String tail) |
| { |
| addText(head); |
| for (Iterator<org.eclipse.ocl.ecore.Variable> iterator = list.iterator(); iterator.hasNext();) |
| { |
| org.eclipse.ocl.ecore.Variable variable = iterator.next(); |
| addText(prefix); |
| unparseVariable(variable,false); |
| if (iterator.hasNext()) |
| addText(separatorSuffix); |
| } |
| addText(tail); |
| } |
| |
| private void unparseVariablesCommaSeparated(EList<Variable<EClassifier, EParameter>> list) |
| { |
| unparseVariables("","",list,",",""); |
| } |
| |
| private void unparseVariables(String head, String prefix, EList<Variable<EClassifier, EParameter>> list, String separatorSuffix, String tail) |
| { |
| addText(head); |
| for (Iterator<Variable<EClassifier, EParameter>> iterator = list.iterator(); iterator.hasNext();) |
| { |
| Variable<EClassifier, EParameter> variable = iterator.next(); |
| addText(prefix); |
| unparseVariable(variable,false); |
| if (iterator.hasNext()) |
| addText(separatorSuffix); |
| } |
| addText(tail); |
| } |
| |
| |
| public Object visitVariableInitExp(VariableInitExp variableInit) |
| { |
| unparseVariableInitExp(variableInit); |
| return null; |
| } |
| |
| private void unparseVariableInitExp(VariableInitExp variableInit) |
| { |
| org.eclipse.ocl.ecore.Variable variable = variableInit.getReferredVariable(); |
| String assignmentOp = variableInit.isWithResult() ? " ::= " : " := "; |
| |
| addText("var "); |
| unparseVariable(variable,false); |
| OCLExpression initExpression = (OCLExpression)variable.getInitExpression(); |
| if ( initExpression != null ) |
| { |
| addText(assignmentOp); |
| unparseOCLExpression(initExpression); |
| } |
| } |
| |
| public Object visitWhileExp(WhileExp vvhile) |
| { |
| unparseWhileExp(vvhile); |
| return null; |
| } |
| |
| private void unparseWhileExp(WhileExp vvhile) |
| { |
| addText("while ( "); |
| unparseOCLExpression(vvhile.getCondition()); |
| addText(" )"); |
| |
| unparseBlockExpBody(vvhile.getBody()); |
| } |
| |
| private void unparseBlockExpBody(OCLExpression body) |
| { |
| if ( body instanceof BlockExp ) |
| { |
| BlockExp block = (BlockExp) body; |
| unparseBlockExp(block,false,false); |
| } |
| else |
| { |
| addText("{ "); |
| unparseOCLExpression(body); |
| addText(" }"); |
| } |
| } |
| |
| public Object visitLetExp(LetExp<EClassifier, EParameter> letExp) |
| { |
| unparseLetExp(letExp); |
| return null; |
| } |
| |
| private void unparseLetExp(LetExp<EClassifier, EParameter> letExp) |
| { |
| // <let_exp> ::= 'let' <declarator_list> 'in' <expression> |
| addText("let "); |
| unparseVariable(letExp.getVariable(),true); |
| addText(" in "); |
| unparseOCLExpression(letExp.getIn()); |
| } |
| |
| private void unparseLiteralExpressions(LiteralExp expression) |
| { |
| if (expression instanceof org.eclipse.ocl.ecore.CollectionLiteralExp) |
| { |
| unparseCollectionLiteralExp((org.eclipse.ocl.ecore.CollectionLiteralExp) expression); |
| } |
| else if (expression instanceof DictLiteralExp) |
| { |
| unparseDictLiteralExp((DictLiteralExp) expression); |
| } |
| else if (expression instanceof org.eclipse.ocl.ecore.EnumLiteralExp) |
| { |
| unparseEnumLiteralExp((org.eclipse.ocl.ecore.EnumLiteralExp) expression); |
| } |
| else if (expression instanceof org.eclipse.ocl.ecore.InvalidLiteralExp) |
| { |
| unparseInvalidLiteralExp((org.eclipse.ocl.ecore.InvalidLiteralExp) expression); |
| } |
| else if (expression instanceof ListLiteralExp) |
| { |
| unparseListLiteralExp((ListLiteralExp)expression); |
| } |
| else if (expression instanceof org.eclipse.ocl.ecore.NullLiteralExp) |
| { |
| unparseNullLiteralExp((org.eclipse.ocl.ecore.NullLiteralExp) expression); |
| } |
| else if (expression instanceof OrderedTupleLiteralExp) |
| { |
| unparseOrderedTupleLiteralExp((OrderedTupleLiteralExp) expression); |
| } |
| else if (expression instanceof PrimitiveLiteralExp) |
| { |
| unparsePrimitiveLiteralExpressions((PrimitiveLiteralExp)expression); |
| } |
| else if (expression instanceof org.eclipse.ocl.ecore.TupleLiteralExp) |
| { |
| unparseTupleLiteralExp((org.eclipse.ocl.ecore.TupleLiteralExp) expression); |
| } |
| } |
| |
| public Object visitCollectionLiteralExp(CollectionLiteralExp<EClassifier> literalExp) |
| { |
| unparseCollectionLiteralExp(literalExp); |
| return null; |
| } |
| |
| private void unparseCollectionLiteralExp(CollectionLiteralExp<EClassifier> literalExp) |
| { |
| if (literalExp.getKind().equals(CollectionKind.SEQUENCE_LITERAL) && literalExp.getType() instanceof ListType ) |
| { |
| unparseCollectionLiteralAsListLiteral(literalExp); |
| return; |
| } |
| String collectionTypeText = literalExp.getKind().getName(); |
| EList<CollectionLiteralPart<EClassifier>> partList = literalExp.getPart(); |
| unparseCollectionLiteralExp_TypeAndParts(collectionTypeText, partList); |
| } |
| |
| private void unparseCollectionLiteralExp_TypeAndParts(String collectionTypeText,EList<CollectionLiteralPart<EClassifier>> partList) |
| { |
| addText(collectionTypeText + " {"); |
| unparseCollectionLiteralParts(partList); |
| addText("}"); |
| } |
| |
| private void unparseCollectionLiteralParts(EList<CollectionLiteralPart<EClassifier>> collectionLiteralPartList) |
| { |
| for (Iterator<CollectionLiteralPart<EClassifier>> partItor = collectionLiteralPartList.iterator(); partItor.hasNext();) |
| { |
| unparseCollectionLiteralPart(partItor.next()); |
| if ( partItor.hasNext() ) addText(","); |
| } |
| } |
| |
| private void unparseCollectionLiteralPart(CollectionLiteralPart<EClassifier> collectionLiteralPart) |
| { |
| if ( collectionLiteralPart instanceof CollectionItem ) |
| { |
| unparseCollectionItem((CollectionItem<EClassifier>) collectionLiteralPart); |
| } |
| else if ( collectionLiteralPart instanceof CollectionRange ) |
| { |
| unparseCollectionRange((CollectionRange<EClassifier>) collectionLiteralPart); |
| } |
| else |
| { |
| addText("/*CollectionLiteralPart*/"); |
| } |
| } |
| |
| public Object visitDictLiteralExp(DictLiteralExp dictLiteral) |
| { |
| unparseDictLiteralExp(dictLiteral); |
| return null; |
| } |
| |
| private void unparseDictLiteralExp(DictLiteralExp dictLiteral) |
| { |
| // <literal_dict> ::= 'Dict' '{' <dict_item_list>? '}' |
| // <dict_item_list> ::= <dict_item> (',' <dict_item>)* |
| // <dict_item> ::= <literal_simple> '=' <expression> |
| addText("Dict {"); |
| unparseDictLiteralParts(dictLiteral.getPart()); |
| addText("}"); |
| } |
| |
| private void unparseDictLiteralParts(EList<DictLiteralPart> dictLiteralPartList) |
| { |
| for (Iterator<DictLiteralPart> partItor = dictLiteralPartList.iterator(); partItor.hasNext();) |
| { |
| unparseDictLiteralPart(partItor.next()); |
| if ( partItor.hasNext() ) addText(","); |
| } |
| } |
| |
| public Object visitDictLiteralPart(DictLiteralPart dictLiteralPart) |
| { |
| unparseDictLiteralPart(dictLiteralPart); |
| return null; |
| } |
| |
| private void unparseDictLiteralPart(DictLiteralPart dictLiteralPart) |
| { |
| unparseOCLExpression(dictLiteralPart.getKey()); |
| addText(" = "); |
| unparseOCLExpression(dictLiteralPart.getValue()); |
| } |
| |
| public Object visitEnumLiteralExp(EnumLiteralExp<EClassifier, EEnumLiteral> enumLiteral) |
| { |
| unparseEnumLiteralExp(enumLiteral); |
| return null; |
| } |
| |
| private void unparseEnumLiteralExp(EnumLiteralExp<EClassifier, EEnumLiteral> enumLiteral) |
| { |
| EEnumLiteral referredEnumLiteral = enumLiteral.getReferredEnumLiteral(); |
| EClassifier enumType = enumLiteral.getType(); |
| unparseType(enumType); |
| |
| String enumName = enumLiteral.getName(); |
| |
| if ( referredEnumLiteral != null ) |
| { |
| enumName = referredEnumLiteral.getLiteral(); |
| } |
| |
| enumName = escapeKeywordName(enumName); |
| |
| addText("::" + enumName); |
| } |
| |
| public Object visitInvalidLiteralExp(InvalidLiteralExp<EClassifier> invalidLiteral) |
| { |
| unparseInvalidLiteralExp(invalidLiteral); |
| return null; |
| } |
| |
| private void unparseInvalidLiteralExp(InvalidLiteralExp<EClassifier> invalidLiteral) |
| { |
| addText("invalid/*___InvalidLiteralExp___*/"); |
| } |
| |
| private void unparseListLiteralExp(ListLiteralExp listLiteral) |
| { |
| addText("List "); |
| unparseOCLExpressionsSemicolonSeparatedInBraces(listLiteral.getElement(), false); |
| } |
| |
| private void unparseCollectionLiteralAsListLiteral(CollectionLiteralExp<EClassifier> collectionLiteral) |
| { |
| unparseCollectionLiteralExp_TypeAndParts("List", collectionLiteral.getPart()); |
| } |
| |
| public Object visitNullLiteralExp(NullLiteralExp<EClassifier> literalExp) |
| { |
| unparseNullLiteralExp(literalExp); |
| return null; |
| } |
| |
| private void unparseNullLiteralExp(NullLiteralExp<EClassifier> literalExp) |
| { |
| addText("null"); |
| } |
| |
| public Object visitOrderedTupleLiteralExp(OrderedTupleLiteralExp tuple) |
| { |
| unparseOrderedTupleLiteralExp(tuple); |
| return null; |
| } |
| |
| private void unparseOrderedTupleLiteralExp(OrderedTupleLiteralExp tuple) |
| { |
| addText("Tuple {"); |
| unparseOrderedTupleLiteralParts(tuple.getPart()); |
| addText("}"); |
| } |
| |
| private void unparseOrderedTupleLiteralParts(EList<OrderedTupleLiteralPart> partList) |
| { |
| for (Iterator<OrderedTupleLiteralPart> partItor = partList.iterator(); partItor.hasNext();) |
| { |
| unparseOrderedTupleLiteralPart(partItor.next()); |
| if ( partItor.hasNext() ) addText(","); |
| } |
| } |
| |
| public Object visitOrderedTupleLiteralPart(OrderedTupleLiteralPart part) |
| { |
| unparseOrderedTupleLiteralPart(part); |
| return null; |
| } |
| |
| private void unparseOrderedTupleLiteralPart(OrderedTupleLiteralPart part) |
| { |
| unparseOCLExpression(part.getValue()); |
| } |
| |
| private void unparsePrimitiveLiteralExpressions(PrimitiveLiteralExp expression) |
| { |
| if (expression instanceof org.eclipse.ocl.ecore.BooleanLiteralExp) |
| { |
| unparseBooleanLiteralExp((org.eclipse.ocl.ecore.BooleanLiteralExp) expression); |
| } |
| else if (expression instanceof NumericLiteralExp) |
| { |
| unparseNumericLiteralExp((NumericLiteralExp) expression); |
| } |
| else if (expression instanceof org.eclipse.ocl.ecore.StringLiteralExp) |
| { |
| unparseStringLiteralExp((org.eclipse.ocl.ecore.StringLiteralExp) expression); |
| } |
| } |
| |
| public Object visitBooleanLiteralExp(BooleanLiteralExp<EClassifier> literal) |
| { |
| unparseBooleanLiteralExp(literal); |
| return null; |
| } |
| |
| private void unparseBooleanLiteralExp(BooleanLiteralExp<EClassifier> literal) |
| { |
| addText(literal.getBooleanSymbol().toString()); |
| } |
| |
| private void unparseNumericLiteralExp(NumericLiteralExp expression) |
| { |
| if (expression instanceof org.eclipse.ocl.ecore.IntegerLiteralExp) |
| { |
| unparseIntegerLiteralExp((org.eclipse.ocl.ecore.IntegerLiteralExp) expression); |
| } |
| else if (expression instanceof org.eclipse.ocl.ecore.RealLiteralExp) |
| { |
| unparseRealLiteralExp((org.eclipse.ocl.ecore.RealLiteralExp) expression); |
| } |
| else if (expression instanceof org.eclipse.ocl.ecore.UnlimitedNaturalLiteralExp) |
| { |
| unparseUnlimitedNaturalLiteralExp((org.eclipse.ocl.ecore.UnlimitedNaturalLiteralExp) expression); |
| } |
| } |
| |
| public Object visitIntegerLiteralExp(IntegerLiteralExp<EClassifier> literal) |
| { |
| unparseIntegerLiteralExp(literal); |
| return null; |
| } |
| |
| private void unparseIntegerLiteralExp(IntegerLiteralExp<EClassifier> literal) |
| { |
| addText(literal.getIntegerSymbol().toString()); |
| } |
| |
| public Object visitRealLiteralExp(RealLiteralExp<EClassifier> literal) |
| { |
| unparseRealLiteralExp(literal); |
| return null; |
| } |
| |
| private void unparseRealLiteralExp(RealLiteralExp<EClassifier> literal) |
| { |
| addText(literal.getRealSymbol().toString()); |
| } |
| |
| public Object visitUnlimitedNaturalLiteralExp(UnlimitedNaturalLiteralExp<EClassifier> literal) |
| { |
| unparseUnlimitedNaturalLiteralExp(literal); |
| return null; |
| } |
| |
| private void unparseUnlimitedNaturalLiteralExp(UnlimitedNaturalLiteralExp<EClassifier> literal) |
| { |
| addText(literal.toString()); |
| } |
| |
| public Object visitStringLiteralExp(StringLiteralExp<EClassifier> literal) |
| { |
| unparseStringLiteralExp(literal); |
| return null; |
| } |
| |
| private void unparseStringLiteralExp(StringLiteralExp<EClassifier> literal) |
| { |
| String stringText = literal.getStringSymbol(); |
| stringText = stringText.replace("\\", "\\\\"); |
| stringText = stringText.replace("'", "\\'"); |
| stringText = stringText.replace("\r", "\\r"); |
| stringText = stringText.replace("\n", "\\n"); |
| stringText = stringText.replace("\t", "\\t"); |
| addText("'" + stringText + "'"); |
| } |
| |
| public Object visitTupleLiteralExp(TupleLiteralExp<EClassifier, EStructuralFeature> tuple) |
| { |
| unparseTupleLiteralExp(tuple); |
| return null; |
| } |
| |
| private void unparseTupleLiteralExp(TupleLiteralExp<EClassifier, EStructuralFeature> tuple) |
| { |
| // <literal_tuple> ::= 'Tuple' '{' <tuple_item_list>? '}' |
| // <tuple_item_list> ::= <declarator_list> |
| addText("Tuple {"); |
| unparseTupleLiteralParts(tuple.getPart()); |
| addText("}"); |
| } |
| |
| private void unparseTupleLiteralParts(EList<TupleLiteralPart<EClassifier, EStructuralFeature>> tupleLiteralPartList) |
| { |
| for (Iterator<TupleLiteralPart<EClassifier, EStructuralFeature>> partItor = tupleLiteralPartList.iterator(); partItor.hasNext();) |
| { |
| unparseTupleLiteralPart(partItor.next()); |
| if ( partItor.hasNext() ) addText(","); |
| } |
| } |
| |
| public Object visitTupleLiteralPart(TupleLiteralPart<EClassifier, EStructuralFeature> part) |
| { |
| unparseTupleLiteralPart(part); |
| return null; |
| } |
| |
| private void unparseTupleLiteralPart(TupleLiteralPart<EClassifier, EStructuralFeature> part) |
| { |
| addText(part.getName() + ":"); |
| unparseType(part.getType()); |
| addText(" = "); |
| unparseOCLExpression(part.getValue()); |
| } |
| |
| public Object visitMessageExp(MessageExp<EClassifier, CallOperationAction, SendSignalAction> message) |
| { |
| unparseMessageExp(message); |
| return null; |
| } |
| |
| private void unparseMessageExp(MessageExp<EClassifier, CallOperationAction, SendSignalAction> message) |
| { |
| unparseOCLExpression(message.getTarget()); |
| if ( message.getCalledOperation() != null ) |
| { |
| addText("^^" + message.getCalledOperation().getOperation().getName()); |
| } |
| else |
| { |
| addText("^^" + message.getSentSignal().getSignal().getName()); |
| } |
| unparseOCLExpressionsCommaSeparatedInParentheses(message.getArgument()); |
| } |
| |
| public Object visitStateExp(StateExp<EClassifier, EObject> state) |
| { |
| unparseStateExp(state); |
| return null; |
| } |
| |
| private void unparseStateExp(StateExp<EClassifier, EObject> state) |
| { |
| addText("oclIsInState(" + state.getReferredState() +")"); |
| } |
| |
| public Object visitTypeExp(TypeExp<EClassifier> expression) |
| { |
| unparseTypeExp(expression); |
| return null; |
| } |
| |
| private void unparseTypeExp(TypeExp<EClassifier> expression) |
| { |
| unparseType(expression.getReferredType()); |
| } |
| |
| public Object visitUnspecifiedValueExp(UnspecifiedValueExp<EClassifier> unspecExp) |
| { |
| unparseUnspecifiedValueExp(unspecExp); |
| return null; |
| } |
| |
| private void unparseUnspecifiedValueExp(UnspecifiedValueExp<EClassifier> unspecExp) |
| { |
| addText("unspecified"); |
| } |
| |
| public Object visitVariableExp(VariableExp<EClassifier, EParameter> variableExp) |
| { |
| unparseVariableExp(variableExp); |
| return null; |
| } |
| |
| private boolean unparseVariableExp(VariableExp<EClassifier, EParameter> variableExp) |
| { |
| String variableName = variableExp.getName(); |
| EClassifier variableType = variableExp.getType(); |
| Variable<EClassifier,EParameter> referredVariable = variableExp.getReferredVariable(); |
| |
| if ( referredVariable == null ) |
| { |
| addText("/*noReferredVariable*/"); |
| addText(variableName); |
| return true; |
| } |
| else |
| { |
| if (variableType instanceof Library ) |
| { |
| String libraryName = variableType.getName(); |
| addText("/*" + libraryName + "." + variableName + "*/"); |
| return false; |
| } |
| else if (variableType instanceof OperationalTransformation ) |
| { |
| String transformationName = variableType.getName(); |
| if ( variableName.equals("this") ) |
| { |
| addText("/*" + transformationName + "." + variableName + "*/"); |
| return false; |
| } |
| else |
| { |
| addText(variableName); |
| return true; |
| } |
| } |
| else |
| { |
| // addText("/*VariableExp*/" + variableName); |
| addText(variableName); |
| return true; |
| } |
| } |
| |
| } |
| |
| public Object visitCollectionItem(CollectionItem<EClassifier> collectionItem) |
| { |
| unparseCollectionItem(collectionItem); |
| return null; |
| } |
| |
| private void unparseCollectionItem(CollectionItem<EClassifier> collectionItem) |
| { |
| unparseOCLExpression(collectionItem.getItem()); |
| } |
| |
| public Object visitCollectionRange(CollectionRange<EClassifier> range) |
| { |
| unparseCollectionRange(range); |
| return null; |
| } |
| |
| private void unparseCollectionRange(CollectionRange<EClassifier> range) |
| { |
| unparseOCLExpression(range.getFirst()); |
| addText(".."); |
| unparseOCLExpression(range.getLast()); |
| } |
| |
| public Object visitVariable(Variable<EClassifier, EParameter> variable) |
| { |
| unparseVariable(variable,false); |
| return null; |
| } |
| |
| private void unparseVariable(Variable<EClassifier, EParameter> variable, boolean withInitExpression) |
| { |
| if ( variable == null ) return; |
| |
| unparseVariableNameType(variable); |
| |
| if ( withInitExpression ) |
| { |
| org.eclipse.ocl.expressions.OCLExpression<EClassifier> initExpression = variable.getInitExpression(); |
| if ( initExpression != null ) |
| { |
| addText(" = "); |
| unparseOCLExpression(initExpression); |
| } |
| } |
| } |
| |
| private void unparseVariableNameType(Variable<EClassifier, EParameter> variable) |
| { |
| unparseVariableNameType(variable,true); |
| } |
| |
| private void unparseVariableNameType(Variable<EClassifier, EParameter> variable, boolean withType) |
| { |
| String variableName = variable.getName(); |
| boolean variableNameIsNotGenerated = !variableNameIsGeneratedTemp(variableName); |
| if ( variableNameIsNotGenerated ) |
| { |
| addText(variableName); |
| } |
| else |
| { |
| addText("/*" + variableName + "*/"); |
| } |
| |
| if ( withType ) |
| { |
| if ( variableNameIsNotGenerated ) |
| { |
| addText(":"); |
| } |
| unparseType(variable.getType()); |
| } |
| } |
| |
| private boolean variableNameIsGeneratedTemp(String variableName) |
| { |
| boolean isGeneratedTemp = |
| variableName.startsWith(QvtEnvironmentBase.GENERATED_NAME_SPECIAL_PREFIX + "temp"); |
| return isGeneratedTemp; |
| } |
| |
| public Object visitExpressionInOCL(ExpressionInOCL<EClassifier, EParameter> expression) |
| { |
| unparseExpressionInOCL(expression); |
| return null; |
| } |
| |
| private void unparseExpressionInOCL(ExpressionInOCL<EClassifier, EParameter> expression) |
| { |
| addText("[TODO]"); //TODO visitExpressionInOCL |
| } |
| |
| public Object visitConstraint(Constraint constraint) |
| { |
| unparseConstraint(constraint); |
| return null; |
| } |
| |
| private void unparseConstraint(Constraint constraint) |
| { |
| addText("[TODO]"); //TODO visitConstraint |
| constraint.getConstrainedElements(); |
| constraint.getSpecification(); |
| constraint.getStereotype(); |
| } |
| |
| public Object visitContextualProperty(ContextualProperty contextualProperty) |
| { |
| unparseContextualProperty(contextualProperty); |
| return null; |
| } |
| |
| private void unparseContextualProperty(ContextualProperty contextualProperty) |
| { |
| // contextualProperty.getOverridden(); |
| String readonlyText = contextualProperty.isChangeable() ? "" : "readonly "; |
| |
| EClass contextClass = contextualProperty.getContext(); |
| String contextClassText = constructFullyQualifiedType(contextClass); |
| |
| String propertyName = contextualProperty.getName(); |
| addText("intermediate " + readonlyText + "property " + contextClassText + "::" + propertyName + ": "); |
| unparseType(contextualProperty.getEType()); |
| |
| org.eclipse.ocl.expressions.OCLExpression<EClassifier> initExpression = contextualProperty.getInitExpression(); |
| if ( initExpression != null ) |
| { |
| addText(" = "); |
| unparseOCLExpression(initExpression); |
| } |
| |
| addText(";"); |
| addLineBreak(); |
| } |
| |
| public Object visitVarParameter(VarParameter parameter) |
| { |
| unparseVarParameter(parameter); |
| return null; |
| } |
| |
| private void unparseVarParameter(VarParameter parameter) |
| { |
| if ( parameter instanceof MappingParameter ) |
| { |
| unparseMappingParameter((MappingParameter)parameter,true); |
| } |
| else |
| { |
| unparseVarParameter(parameter,true); |
| } |
| } |
| |
| private void unparseVarParameter(VarParameter parameter, boolean withDirectionAndName) |
| { |
| String direction = parameter.getKind().getLiteral(); |
| String name = parameter.getName(); |
| String directionAndName = withDirectionAndName ? "" + direction + " " + name + " : " : ""; |
| |
| addText(directionAndName); |
| |
| unparseVarParameterType(parameter.getType()); |
| } |
| |
| private void unparseVarParameterType(EClassifier parameterType) |
| { |
| if (parameterType instanceof CollectionType ) |
| { |
| unparseVarParameterCollectionType((CollectionType)parameterType); |
| } |
| else |
| { |
| unparseType(parameterType); |
| } |
| } |
| |
| private void unparseVarParameterCollectionType(CollectionType collectionType) |
| { |
| if ( collectionType instanceof ListType ) { |
| addText("List ("); |
| } |
| else if ( collectionType instanceof SequenceType ) { |
| addText("Sequence ("); |
| } |
| else if ( collectionType instanceof OrderedSetType ) { |
| addText("OrderedSet ("); |
| } |
| else if ( collectionType instanceof SetType ) { |
| addText("Set ("); |
| } |
| else if ( collectionType instanceof BagType ) { |
| addText("Bag ("); |
| } |
| else if ( collectionType instanceof DictionaryType ) { |
| addText("Dict ("); |
| DictionaryType dictionaryType = (DictionaryType) collectionType; |
| unparseVarParameterType(dictionaryType.getKeyType()); |
| addText(","); |
| } |
| else |
| { |
| addText("Collection ("); |
| } |
| |
| unparseVarParameterType(collectionType.getElementType()); |
| |
| addText(")"); |
| } |
| |
| private void unparseVarParameters(EList<VarParameter> parameters, boolean withDirectionAndName) |
| { |
| if ( parameters == null || parameters.size() == 0 ) return; |
| |
| addText(" : "); |
| |
| if ( parameters.size() == 1 ) |
| { |
| withDirectionAndName = false; |
| } |
| |
| for (Iterator<VarParameter> iterator = parameters.iterator(); iterator.hasNext();) |
| { |
| VarParameter parameter = iterator.next(); |
| unparseVarParameter(parameter,withDirectionAndName); |
| if ( iterator.hasNext() ) |
| { |
| addText(", "); |
| } |
| } |
| } |
| |
| private String escapeKeywordName(String name) |
| { |
| if ( QvtKeywords.KEYWORDS.contains(name) ) |
| { |
| return "_" + name; |
| } |
| else |
| { |
| return name; |
| } |
| } |
| |
| /** |
| * Handling of generated text fragments |
| */ |
| |
| private List<String> lines = new ArrayList<String>(); |
| private StringBuilder currentLine = new StringBuilder(1024); |
| |
| private int indentationLevel = 0; |
| private String[] indentation = { |
| "", "\t", "\t\t", "\t\t\t", "\t\t\t\t", "\t\t\t\t\t", |
| "\t\t\t\t\t\t", "\t\t\t\t\t\t\t", "\t\t\t\t\t\t\t\t", |
| "\t\t\t\t\t\t\t\t\t", "\t\t\t\t\t\t\t\t\t\t" |
| }; |
| |
| private void indent() |
| { |
| indentationLevel++; |
| } |
| |
| private void unindent() |
| { |
| if ( indentationLevel > 0 ) |
| indentationLevel--; |
| } |
| |
| public List<String> getLines() |
| { |
| if ( currentLine.length() > 0 ) |
| { |
| addLineBreak(); |
| } |
| return lines; |
| } |
| |
| private void addText(String text) |
| { |
| if ( text == null || text.length() == 0 ) return; |
| |
| if ( currentLine.length() == 0 ) |
| { |
| currentLine.append(indentation[indentationLevel]); |
| } |
| currentLine.append(text); |
| } |
| |
| private void addTextAndIndent(String text) |
| { |
| addText(text); |
| indent(); |
| } |
| |
| private void unindentAndAddText(String text) |
| { |
| unindent(); |
| addText(text); |
| } |
| |
| private void addLineBreak() |
| { |
| lines.add(currentLine.toString()); |
| currentLine.setLength(0); |
| } |
| |
| private void addEmptyLine() |
| { |
| if ( currentLine.length() > 0 ) |
| { |
| addLineBreak(); |
| } |
| addLineBreak(); |
| } |
| |
| |
| /* |
| * Notes on QVToParser issues |
| * |
| * Helper.isQuery not set --> bug489092 |
| * Library.isBlackbox not set |
| * MappingCallExp.setOperationCode --> bug489093 |
| * CollectionLiteralExp.kind always "Set": worked around in this Unparser |
| */ |
| } |