| /******************************************************************************* |
| * Copyright (c) 2008, 2015 Borland Software Corporation 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: |
| * Borland Software Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.m2m.internal.qvt.oml.stdlib; |
| |
| import java.util.LinkedHashSet; |
| import java.util.Set; |
| |
| import org.eclipse.emf.ecore.EClassifier; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.m2m.internal.qvt.oml.Messages; |
| import org.eclipse.m2m.internal.qvt.oml.NLS; |
| import org.eclipse.m2m.internal.qvt.oml.ast.env.ModelParameterExtent; |
| import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtOperationalEvaluationEnv; |
| import org.eclipse.m2m.internal.qvt.oml.evaluator.ModelInstance; |
| import org.eclipse.m2m.internal.qvt.oml.evaluator.ModuleInstance; |
| import org.eclipse.m2m.internal.qvt.oml.expressions.ModelType; |
| import org.eclipse.ocl.types.OCLStandardLibrary; |
| import org.eclipse.ocl.util.TypeUtil; |
| import org.eclipse.ocl.utilities.PredefinedType; |
| |
| |
| public class ModelOperations extends AbstractContextualOperations { |
| |
| public static final String CREATE_EMPTY_MODEL_NAME = "createEmptyModel"; //$NON-NLS-1$ |
| public static final String COPY_NAME = "copy"; //$NON-NLS-1$ |
| public static final String OBJECTS_NAME = "objects"; //$NON-NLS-1$ |
| public static final String ROOT_OBJECTS_NAME = "rootObjects"; //$NON-NLS-1$ |
| public static final String OBJECTS_OF_TYPE_NAME = "objectsOfType"; //$NON-NLS-1$ |
| public static final String OBJECTS_OF_KIND_NAME = "objectsOfKind"; //$NON-NLS-1$ |
| public static final String REMOVE_ELEMENT_NAME = "removeElement"; //$NON-NLS-1$ |
| |
| public ModelOperations(AbstractQVTStdlib library) { |
| super(library, library.getModelClass()); |
| } |
| |
| @Override |
| protected OperationProvider[] getOperations() { |
| OCLStandardLibrary<EClassifier> oclStdLibrary = getStdlib().getEnvironment().getOCLStandardLibrary(); |
| EClassifier setOfElements = TypeUtil.resolveSetType(getStdlib().getEnvironment(), getStdlib().getElementType()); |
| EClassifier setOfT = TypeUtil.resolveSetType(getStdlib().getEnvironment(), oclStdLibrary.getT()); |
| return new OperationProvider[] { |
| new OwnedOperationProvider(UNSUPPORTED_OPER, "asTransformation", new String[] { "model" }, //$NON-NLS-1$ //$NON-NLS-2$ |
| getStdlib().getTransformationClass(), getStdlib().getModelClass()), |
| new OwnedOperationProvider(COPY, COPY_NAME, getStdlib().getModelClass()), |
| |
| createOwnedStaticOperationProvider(CREATE_EMPTY_MODEL, CREATE_EMPTY_MODEL_NAME, null, oclStdLibrary.getT()), |
| |
| new OwnedOperationProvider(OBJECTS, OBJECTS_NAME, setOfElements), |
| new OwnedOperationProvider(OBJECTS_OF_TYPE, OBJECTS_OF_TYPE_NAME, new String[] { "type" }, //$NON-NLS-1$ |
| setOfT, oclStdLibrary.getOclType()), |
| new OwnedOperationProvider(OBJECTS_OF_KIND, OBJECTS_OF_KIND_NAME, new String[] { "type" }, //$NON-NLS-1$ |
| setOfT, oclStdLibrary.getOclType()), |
| new OwnedOperationProvider(REMOVE_ELEMENT, REMOVE_ELEMENT_NAME, new String[] { "element" }, //$NON-NLS-1$ |
| oclStdLibrary.getOclVoid(), getStdlib().getElementType()), |
| new OwnedOperationProvider(ROOT_OBJECTS, ROOT_OBJECTS_NAME, setOfElements), |
| |
| new OperationProvider(OBJECTS_OF_KIND, PredefinedType.ALL_INSTANCES_NAME, |
| setOfT, TypeUtil.resolveType(getStdlib().getEnvironment(), oclStdLibrary.getOclType())) |
| .deprecateBy("Model::objectsOfKind(OclType)"), //$NON-NLS-1$ |
| |
| }; |
| } |
| |
| private static final CallHandler OBJECTS = new CallHandler() { |
| public Object invoke(ModuleInstance module, Object source, Object[] args, QvtOperationalEvaluationEnv evalEnv) { |
| if(source instanceof ModelInstance == false) { |
| throw new IllegalArgumentException(NLS.bind(Messages.InvalidSourceForOperationCall, OBJECTS_NAME)); |
| } |
| |
| return getObjects((ModelInstance) source, null, ElementOperations.FILTER_ALL, evalEnv); |
| } |
| }; |
| |
| private static final CallHandler ROOT_OBJECTS = new CallHandler() { |
| public Object invoke(ModuleInstance module, Object source, Object[] args, QvtOperationalEvaluationEnv evalEnv) { |
| if(source instanceof ModelInstance == false) { |
| throw new IllegalArgumentException(NLS.bind(Messages.InvalidSourceForOperationCall, ROOT_OBJECTS_NAME)); |
| } |
| |
| Set<Object> instances = new LinkedHashSet<Object>(); |
| ModelInstance model = (ModelInstance) source; |
| ModelParameterExtent modelParam = model.getExtent(); |
| instances.addAll(modelParam.getRootObjects()); |
| return instances; |
| } |
| }; |
| |
| private static final CallHandler OBJECTS_OF_TYPE = new CallHandler() { |
| public Object invoke(ModuleInstance module, Object source, Object[] args, QvtOperationalEvaluationEnv evalEnv) { |
| if(source instanceof ModelInstance == false) { |
| throw new IllegalArgumentException(NLS.bind(Messages.InvalidSourceForOperationCall, OBJECTS_OF_TYPE_NAME)); |
| } |
| |
| EClassifier type = ElementOperations.getTypeFilterArg(args); |
| return getObjects((ModelInstance) source, type, ElementOperations.FILTER_OF_TYPE, evalEnv); |
| } |
| }; |
| |
| private static final CallHandler OBJECTS_OF_KIND = new CallHandler() { |
| public Object invoke(ModuleInstance module, Object source, Object[] args, QvtOperationalEvaluationEnv evalEnv) { |
| if(source instanceof ModelInstance == false) { |
| throw new IllegalArgumentException(NLS.bind(Messages.InvalidSourceForOperationCall, OBJECTS_OF_KIND_NAME)); |
| } |
| |
| EClassifier type = ElementOperations.getTypeFilterArg(args); |
| return getObjects((ModelInstance) source, type, ElementOperations.FILTER_OF_KIND, evalEnv); |
| } |
| }; |
| |
| private static final CallHandler REMOVE_ELEMENT = new CallHandler() { |
| public Object invoke(ModuleInstance module, Object source, Object[] args, QvtOperationalEvaluationEnv evalEnv) { |
| if(source instanceof ModelInstance == false) { |
| throw new IllegalArgumentException(NLS.bind(Messages.InvalidSourceForOperationCall, REMOVE_ELEMENT_NAME)); |
| } |
| ModelInstance model = (ModelInstance) source; |
| ModelParameterExtent modelParam = model.getExtent(); |
| Object elementObject = args[0]; |
| if(elementObject instanceof EObject) { |
| modelParam.removeElement((EObject) elementObject); |
| } |
| return null; |
| } |
| }; |
| |
| private static final CallHandler COPY = new CallHandler() { |
| public Object invoke(ModuleInstance module, Object source, Object[] args, QvtOperationalEvaluationEnv evalEnv) { |
| if(source instanceof ModelInstance == false) { |
| throw new IllegalArgumentException(NLS.bind(Messages.InvalidSourceForOperationCall, COPY_NAME)); |
| } |
| ModelInstance model = (ModelInstance) source; |
| ModelInstance modelCopy = model.copy(); |
| evalEnv.addModelExtent(modelCopy.getExtent()); |
| return modelCopy; |
| } |
| }; |
| |
| private static final CallHandler CREATE_EMPTY_MODEL = new CallHandler() { |
| public Object invoke(ModuleInstance module, Object source, Object[] args, QvtOperationalEvaluationEnv evalEnv) { |
| if(source instanceof ModelType == false) { |
| throw new IllegalArgumentException(NLS.bind(Messages.InvalidSourceForOperationCall, CREATE_EMPTY_MODEL_NAME)); |
| } |
| |
| ModelType modelType = (ModelType) source; |
| // TODO - user typed factory, beware of special handling with top-level model types |
| // as these do not have |
| EObject modelObj = modelType.getEPackage().getEFactoryInstance().create(modelType); |
| assert modelObj instanceof ModelInstance : "model must implement ModelInstance interface"; //$NON-NLS-1$ |
| return modelObj; |
| } |
| }; |
| |
| static Object getObjects(ModelInstance model, EClassifier type, final int filterFlag, QvtOperationalEvaluationEnv evalEnv) { |
| Set<Object> instances = new LinkedHashSet<Object>(); |
| ModelParameterExtent modelParam = model.getExtent(); |
| for (Object obj : modelParam.getAllObjects()) { |
| boolean accept = filterFlag == ElementOperations.FILTER_ALL; |
| if(ElementOperations.FILTER_OF_KIND == filterFlag) { |
| accept = evalEnv.isKindOf(obj, type); |
| } else if(ElementOperations.FILTER_OF_TYPE == filterFlag) { |
| accept = evalEnv.isTypeOf(obj, type); |
| } |
| if(accept) { |
| instances.add(obj); |
| } |
| } |
| return instances; |
| } |
| |
| } |