/******************************************************************************* * Copyright (c) 2005 - 2009 itemis AG (http://www.itemis.eu) 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 * *******************************************************************************/ package org.eclipse.xtend.typesystem.xsd.type; import java.util.Collection; import java.util.Collections; import java.util.Map; import java.util.Set; import org.eclipse.emf.common.util.EMap; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EClassifier; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.ETypedElement; import org.eclipse.internal.xtend.type.baseimpl.OperationImpl; import org.eclipse.xtend.typesystem.AbstractTypeImpl; import org.eclipse.xtend.typesystem.Feature; import org.eclipse.xtend.typesystem.Type; import org.eclipse.xtend.typesystem.xsd.XSDMetaModel; /** * @author Moritz Eysholdt - Initial contribution and API */ public class EMapType extends AbstractTypeImpl { public static boolean isEMap(ETypedElement element) { EClassifier t = element.getEType(); return element != null && element.eContainer() instanceof EClass && t != null && t.getInstanceClass() != null && Map.Entry.class.isAssignableFrom(t.getInstanceClass()) && element.isMany(); } public static boolean isEMapObject(Object o) { return o instanceof EMap && o instanceof EStructuralFeature.Setting && isEMap(((EStructuralFeature.Setting) o) .getEStructuralFeature()); } private EMapEntryType elementType; private EClassifier innerType; // private EmfRegistryMetaModel model; // private Type valueType; public EMapType(final XSDMetaModel model, final String name, final EClassifier innerType) { super(model.getTypeSystem(), name); // this.model = model; this.innerType = innerType; elementType = model.getEMapEntryType(innerType); } @Override public Feature[] getContributedFeatures() { Type keyType = elementType.getKeyType(); Type valueType = elementType.getValueType(); return new Feature[] { new OperationImpl(this, "put", valueType, keyType, valueType) { @Override @SuppressWarnings("unchecked") protected Object evaluateInternal(Object t, Object[] params) { EMap map = (EMap) t; return map.put(params[0], params[1]); } }, new OperationImpl(this, "put", valueType, elementType) { @Override @SuppressWarnings("unchecked") protected Object evaluateInternal(Object t, Object[] params) { EMap map = (EMap) t; Map.Entry<Object, Object> e = (Map.Entry<Object, Object>) params[0]; return map.put(e.getKey(), e.getValue()); } }, new OperationImpl(this, "putAll", getTypeSystem().getVoidType(), getTypeSystem() .getCollectionType(elementType)) { @Override @SuppressWarnings("unchecked") protected Object evaluateInternal(Object t, Object[] params) { EMap map = (EMap) t; for (Object o : (Collection) params[0]) { Map.Entry<Object, Object> e = (Map.Entry<Object, Object>) o; map.put(e.getKey(), e.getValue()); } return null; } }, new OperationImpl(this, "get", valueType, keyType) { @Override @SuppressWarnings("unchecked") protected Object evaluateInternal(Object t, Object[] params) { EMap map = (EMap) t; return map.get(params[0]); } }, new OperationImpl(this, "indexOfKey", getTypeSystem() .getIntegerType(), keyType) { @Override @SuppressWarnings("unchecked") protected Object evaluateInternal(Object t, Object[] params) { EMap map = (EMap) t; return map.indexOfKey(params[0]); } }, new OperationImpl(this, "containsKey", getTypeSystem() .getBooleanType(), keyType) { @Override @SuppressWarnings("unchecked") protected Object evaluateInternal(Object t, Object[] params) { EMap map = (EMap) t; return map.containsKey(params[0]); } }, new OperationImpl(this, "containsValue", getTypeSystem() .getBooleanType(), valueType) { @Override @SuppressWarnings("unchecked") protected Object evaluateInternal(Object t, Object[] params) { EMap map = (EMap) t; return map.containsValue(params[0]); } }, new OperationImpl(this, "removeKey", valueType, keyType) { @Override @SuppressWarnings("unchecked") protected Object evaluateInternal(Object t, Object[] params) { EMap map = (EMap) t; return map.removeKey(params[0]); } }, new OperationImpl(this, "keySet", getTypeSystem().getSetType( keyType)) { @Override @SuppressWarnings("unchecked") protected Object evaluateInternal(Object t, Object[] params) { EMap map = (EMap) t; return map.keySet(); } }, new OperationImpl(this, "values", getTypeSystem() .getCollectionType(valueType)) { @Override @SuppressWarnings("unchecked") protected Object evaluateInternal(Object t, Object[] params) { EMap map = (EMap) t; return map.values(); } } }; } @Override public Set<? extends Type> getSuperTypes() { return Collections.singleton(getTypeSystem().getListType(elementType)); } public EClassifier getInnerType() { return innerType; } public boolean isInstance(Object o) { return isEMapObject(o); } public Object newInstance() { throw new UnsupportedOperationException( "EMaps can not be instantiated outside EObjects"); } }