/*******************************************************************************
* Copyright (c) 2014, 2015 S.Boyko 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:
* Sergey Boyko - initial API and implementation
*******************************************************************************/
package org.eclipse.m2m.internal.qvt.oml.stdlib;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
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.types.OCLStandardLibrary;
import org.eclipse.ocl.util.CollectionUtil;
import org.eclipse.ocl.util.TypeUtil;
import org.eclipse.ocl.utilities.PredefinedType;
public class OrderedSetTypeOperations extends AbstractContextualOperations {
static final String REVERSE_NAME = "reverse"; //$NON-NLS-1$
private OrderedSetTypeOperations(AbstractQVTStdlib library, EClassifier contextType) {
super(library, contextType);
}
public static AbstractContextualOperations[] getAllOperations(AbstractQVTStdlib library) {
QVTOEnvironment environment = library.getEnvironment();
return new AbstractContextualOperations[] {
new OrderedSetTypeOperations(library, environment.getOCLStandardLibrary().getOrderedSet()),
};
}
@Override
protected OperationProvider[] getOperations() {
OCLStandardLibrary<EClassifier> oclStdlib = getStdlib().getEnvironment().getOCLStandardLibrary();
EClassifier orderedSetOfCommonT = TypeUtil.resolveOrderedSetType(getStdlib().getEnvironment(), getStdlib().getCommonT());
return new OperationProvider[] {
// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=467600
//
new OperationProvider(APPEND, PredefinedType.APPEND_NAME, new String[] {"object"}, //$NON-NLS-1$
orderedSetOfCommonT, oclStdlib.getT2()),
new OperationProvider(PREPEND, PredefinedType.PREPEND_NAME, new String[] {"object"}, //$NON-NLS-1$
orderedSetOfCommonT, oclStdlib.getT2()),
new OperationProvider(INSERT_AT, PredefinedType.INSERT_AT_NAME, new String[] {"index", "object"}, //$NON-NLS-1$ //$NON-NLS-2$
orderedSetOfCommonT, oclStdlib.getInteger(), oclStdlib.getT2()),
new OperationProvider(INDEX_OF, PredefinedType.INDEX_OF_NAME, new String[] {"object"}, //$NON-NLS-1$
oclStdlib.getInteger(), oclStdlib.getT2()),
new OperationProvider(REVERSE, REVERSE_NAME, oclStdlib.getOrderedSet()),
};
}
static final CallHandler APPEND = new CallHandler() {
@SuppressWarnings("unchecked")
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);
}
Collection<?> result = CollectionUtil.append((Collection<Object>) source, args[0]);
if (source instanceof MutableList && false == result instanceof MutableList) {
result = Utils.createList(result);
}
return result;
}
return CallHandlerAdapter.getInvalidResult(evalEnv);
}
};
static final CallHandler PREPEND = new CallHandler() {
@SuppressWarnings("unchecked")
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);
}
Collection<?> result = CollectionUtil.prepend((Collection<Object>) source, args[0]);
if (source instanceof MutableList && false == result instanceof MutableList) {
result = Utils.createList(result);
}
return result;
}
return CallHandlerAdapter.getInvalidResult(evalEnv);
}
};
static final CallHandler INSERT_AT = new CallHandler() {
@SuppressWarnings("unchecked")
public Object invoke(ModuleInstance module, Object source, Object[] args, QvtOperationalEvaluationEnv evalEnv) {
if(source instanceof Collection && args.length > 1 && args[0] instanceof Integer) {
if (args[1] == CallHandlerAdapter.getInvalidResult(evalEnv)) {
return CallHandlerAdapter.getInvalidResult(evalEnv);
}
Collection<?> result = CollectionUtil.insertAt((Collection<Object>) source, (Integer) args[0], args[1]);
if (source instanceof MutableList && false == result instanceof MutableList) {
result = Utils.createList(result);
}
return result;
}
return CallHandlerAdapter.getInvalidResult(evalEnv);
}
};
static final CallHandler INDEX_OF = 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);
}
Integer index = CollectionUtil.indexOf((Collection<?>) source, args[0]);
if (index == null) {
return CallHandlerAdapter.getInvalidResult(evalEnv);
}
return index;
}
return CallHandlerAdapter.getInvalidResult(evalEnv);
}
};
static final CallHandler REVERSE = new CallHandler() {
public Object invoke(ModuleInstance module, Object source, Object[] args, QvtOperationalEvaluationEnv evalEnv) {
if(source instanceof Collection) {
List<?> result = new ArrayList<Object>((Collection<?>) source);
Collections.reverse(result);
if (source instanceof MutableList) {
return EvaluationUtil.asList(result);
}
if (source instanceof LinkedHashSet) {
return CollectionUtil.asOrderedSet(result);
}
return CollectionUtil.asSequence(result);
}
return CallHandlerAdapter.getInvalidResult(evalEnv);
}
};
}