blob: 621fa1fe08a96962cbd093610fa3579d6c3486a8 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2014, 2018 S.Boyko and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Sergey Boyko - initial API and implementation
*******************************************************************************/
package org.eclipse.m2m.internal.qvt.oml.stdlib;
import java.util.Collection;
import java.util.LinkedHashSet;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.m2m.internal.qvt.oml.ast.env.QVTOEnvironment;
import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtOperationalEvaluationEnv;
import org.eclipse.m2m.internal.qvt.oml.evaluator.EvaluationUtil;
import org.eclipse.m2m.internal.qvt.oml.evaluator.ModuleInstance;
import org.eclipse.m2m.qvt.oml.util.MutableList;
import org.eclipse.m2m.qvt.oml.util.Utils;
import org.eclipse.ocl.expressions.CollectionKind;
import org.eclipse.ocl.types.OCLStandardLibrary;
import org.eclipse.ocl.util.CollectionUtil;
import org.eclipse.ocl.util.ObjectUtil;
import org.eclipse.ocl.util.TypeUtil;
import org.eclipse.ocl.utilities.PredefinedType;
public class CollectionTypeOperations extends AbstractContextualOperations {
static final String AS_LIST_NAME = "asList"; //$NON-NLS-1$
private CollectionTypeOperations(AbstractQVTStdlib library, EClassifier contextType) {
super(library, contextType);
}
public static AbstractContextualOperations[] getAllOperations(AbstractQVTStdlib library) {
QVTOEnvironment environment = library.getEnvironment();
return new AbstractContextualOperations[] {
new CollectionTypeOperations(library, environment.getOCLStandardLibrary().getCollection()),
};
}
@Override
protected OperationProvider[] getOperations() {
OCLStandardLibrary<EClassifier> oclStdlib = getStdlib().getEnvironment().getOCLStandardLibrary();
EClassifier collectionOfT2 = TypeUtil.resolveCollectionType(getStdlib().getEnvironment(),
CollectionKind.COLLECTION_LITERAL, oclStdlib.getT2());
return new OperationProvider[] {
new OperationProvider(AS_SET, PredefinedType.AS_SET_NAME, oclStdlib.getSet()),
new OperationProvider(AS_ORDERED_SET, PredefinedType.AS_ORDERED_SET_NAME, oclStdlib.getOrderedSet()),
new OperationProvider(AS_SEQUENCE, PredefinedType.AS_SEQUENCE_NAME, oclStdlib.getSequence()),
new OperationProvider(AS_BAG, PredefinedType.AS_BAG_NAME, oclStdlib.getBag()),
new OperationProvider(AS_LIST, AS_LIST_NAME, getStdlib().getList()),
new OperationProvider(FLATTEN, PredefinedType.FLATTEN_NAME, collectionOfT2),
new OperationProvider(ObjectOperations.REPR, ObjectOperations.REPR_NAME, oclStdlib.getString()),
new OperationProvider(StdlibModuleOperations.DUMP, StdlibModuleOperations.DUMP_NAME,
oclStdlib.getOclVoid()).deprecate(),
// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=467600
//
new OperationProvider(INCLUDES, PredefinedType.INCLUDES_NAME, new String[] {"object"}, //$NON-NLS-1$
oclStdlib.getBoolean(), oclStdlib.getT2()),
new OperationProvider(EXCLUDES, PredefinedType.EXCLUDES_NAME, new String[] {"object"}, //$NON-NLS-1$
oclStdlib.getBoolean(), oclStdlib.getT2()),
new OperationProvider(COUNT, PredefinedType.COUNT_NAME, new String[] {"object"}, //$NON-NLS-1$
oclStdlib.getInteger(), oclStdlib.getT2()),
new OperationProvider(INCLUDES_ALL, PredefinedType.INCLUDES_ALL_NAME, new String[] {"c2"}, //$NON-NLS-1$
oclStdlib.getBoolean(), collectionOfT2),
new OperationProvider(EXCLUDES_ALL, PredefinedType.EXCLUDES_ALL_NAME, new String[] {"c2"}, //$NON-NLS-1$
oclStdlib.getBoolean(), collectionOfT2),
new OperationProvider(EQUAL, PredefinedType.EQUAL_NAME, new String[] {"c"}, //$NON-NLS-1$
oclStdlib.getBoolean(), collectionOfT2),
new OperationProvider(NOT_EQUAL, PredefinedType.NOT_EQUAL_NAME, new String[] {"c"}, //$NON-NLS-1$
oclStdlib.getBoolean(), collectionOfT2),
};
}
private static final CallHandler AS_SET = new CallHandler() {
public Object invoke(ModuleInstance module, Object source, Object[] args, QvtOperationalEvaluationEnv evalEnv) {
if(source instanceof Collection) {
return CollectionUtil.asSet((Collection<?>) source);
}
return CallHandlerAdapter.getInvalidResult(evalEnv);
}
};
private static final CallHandler AS_ORDERED_SET = new CallHandler() {
public Object invoke(ModuleInstance module, Object source, Object[] args, QvtOperationalEvaluationEnv evalEnv) {
if(source instanceof Collection) {
return CollectionUtil.asOrderedSet((Collection<?>) source);
}
return CallHandlerAdapter.getInvalidResult(evalEnv);
}
};
private static final CallHandler AS_SEQUENCE = new CallHandler() {
public Object invoke(ModuleInstance module, Object source, Object[] args, QvtOperationalEvaluationEnv evalEnv) {
if(source instanceof Collection) {
if (source instanceof MutableList) {
return CollectionUtil.createNewSequence((Collection<?>) source);
}
return CollectionUtil.asSequence((Collection<?>) source);
}
return CallHandlerAdapter.getInvalidResult(evalEnv);
}
};
private static final CallHandler AS_BAG = new CallHandler() {
public Object invoke(ModuleInstance module, Object source, Object[] args, QvtOperationalEvaluationEnv evalEnv) {
if(source instanceof Collection) {
return CollectionUtil.asBag((Collection<?>) source);
}
return CallHandlerAdapter.getInvalidResult(evalEnv);
}
};
private static final CallHandler AS_LIST = new CallHandler() {
public Object invoke(ModuleInstance module, Object source, Object[] args, QvtOperationalEvaluationEnv evalEnv) {
if(source instanceof Collection) {
return EvaluationUtil.asList((Collection<?>) source);
}
return CallHandlerAdapter.getInvalidResult(evalEnv);
}
};
static final CallHandler FLATTEN = new CallHandler() {
public Object invoke(ModuleInstance module, Object source, Object[] args, QvtOperationalEvaluationEnv evalEnv) {
if(source instanceof Collection) {
Collection<?> self = (Collection<?>) source;
if (self instanceof LinkedHashSet) {
self = CollectionUtil.createNewSet(self);
}
Collection<?> result = CollectionUtil.flatten(self);
if (source instanceof MutableList) {
if (false == result instanceof MutableList || source == result) {
result = Utils.createList(result);
}
}
return result;
}
return CallHandlerAdapter.getInvalidResult(evalEnv);
}
};
private static final CallHandler INCLUDES = new CallHandler() {
public Object invoke(ModuleInstance module, Object source, Object[] args, QvtOperationalEvaluationEnv evalEnv) {
if(source instanceof Collection && args.length > 0) {
if (args[0] == CallHandlerAdapter.getInvalidResult(evalEnv)) {
return CallHandlerAdapter.getInvalidResult(evalEnv);
}
return CollectionUtil.includes((Collection<?>) source, args[0]);
}
return CallHandlerAdapter.getInvalidResult(evalEnv);
}
};
private static final CallHandler EXCLUDES = new CallHandler() {
public Object invoke(ModuleInstance module, Object source, Object[] args, QvtOperationalEvaluationEnv evalEnv) {
if(source instanceof Collection && args.length > 0) {
if (args[0] == CallHandlerAdapter.getInvalidResult(evalEnv)) {
return CallHandlerAdapter.getInvalidResult(evalEnv);
}
return CollectionUtil.excludes((Collection<?>) source, args[0]);
}
return CallHandlerAdapter.getInvalidResult(evalEnv);
}
};
private static final CallHandler COUNT = new CallHandler() {
public Object invoke(ModuleInstance module, Object source, Object[] args, QvtOperationalEvaluationEnv evalEnv) {
if(source instanceof Collection && args.length > 0) {
if (args[0] == CallHandlerAdapter.getInvalidResult(evalEnv)) {
return CallHandlerAdapter.getInvalidResult(evalEnv);
}
return CollectionUtil.count((Collection<?>) source, args[0]);
}
return CallHandlerAdapter.getInvalidResult(evalEnv);
}
};
private static final CallHandler INCLUDES_ALL = new CallHandler() {
public Object invoke(ModuleInstance module, Object source, Object[] args, QvtOperationalEvaluationEnv evalEnv) {
if(source instanceof Collection && args.length > 0 && args[0] instanceof Collection) {
return CollectionUtil.includesAll((Collection<?>) source, (Collection<?>) args[0]);
}
return CallHandlerAdapter.getInvalidResult(evalEnv);
}
};
private static final CallHandler EXCLUDES_ALL = new CallHandler() {
public Object invoke(ModuleInstance module, Object source, Object[] args, QvtOperationalEvaluationEnv evalEnv) {
if(source instanceof Collection && args.length > 0 && args[0] instanceof Collection) {
return CollectionUtil.excludesAll((Collection<?>) source, (Collection<?>) args[0]);
}
return CallHandlerAdapter.getInvalidResult(evalEnv);
}
};
private static final CallHandler EQUAL = new CallHandler() {
public Object invoke(ModuleInstance module, Object source, Object[] args, QvtOperationalEvaluationEnv evalEnv) {
if(source instanceof Collection && args.length > 0) {
if (args[0] == CallHandlerAdapter.getInvalidResult(evalEnv)) {
return CallHandlerAdapter.getInvalidResult(evalEnv);
}
return Boolean.valueOf(ObjectUtil.equal(source, args[0]));
}
return CallHandlerAdapter.getInvalidResult(evalEnv);
}
};
private static final CallHandler NOT_EQUAL = new CallHandler() {
public Object invoke(ModuleInstance module, Object source, Object[] args, QvtOperationalEvaluationEnv evalEnv) {
if(source instanceof Collection && args.length > 0) {
if (args[0] == CallHandlerAdapter.getInvalidResult(evalEnv)) {
return CallHandlerAdapter.getInvalidResult(evalEnv);
}
return Boolean.valueOf(!ObjectUtil.equal(source, args[0]));
}
return CallHandlerAdapter.getInvalidResult(evalEnv);
}
};
}