/******************************************************************************* * Copyright (c) 2013 Olivier Moises * * 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: * Olivier Moises- initial API and implementation *******************************************************************************/ package org.eclipse.wazaabi.locationpaths.runtime; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.util.FeatureMap; import org.eclipse.wazaabi.locationpaths.model.Axis; public class FeatureMapEvaluator { protected static List<?> evaluate(FeatureMap fm, int axis, String nameTest) { if (fm == null) return Collections.emptyList(); switch (axis) { case Axis.CHILD: { List<Object> result = new ArrayList<Object>(30); for (EObject child : getEContent(fm)) { if ((nameTest != null && nameTest.equals(child.eClass() .getName())) || nameTest == null || "*".equals(nameTest)) if (child != null) result.add(child); } return result; } case Axis.DESCENDANT_OR_SELF: break; case Axis.PARENT: // only FeatureMap.Internal provides a way to access its owner (aka // EObject) if (nameTest == null && fm instanceof FeatureMap.Internal && ((FeatureMap.Internal) fm).getEObject() .eContainer() != null) { List<Object> result = new ArrayList<Object>(1); result.add(((FeatureMap.Internal) fm).getEObject() .eContainer()); return result; } break; case Axis.CLASS: // only FeatureMap.Internal provides a way to access its owner (aka // EObject) if (nameTest == null && fm instanceof FeatureMap.Internal) { List<Object> result = new ArrayList<Object>(1); result.add(((FeatureMap.Internal) fm).getEObject() .eClass()); return result; } break; case Axis.PACKAGE: if (nameTest == null) { List<Object> result = new ArrayList<Object>(1); if (fm instanceof EClass) result.add(((EClass) fm).getEPackage()); else if (fm instanceof FeatureMap.Internal) // only FeatureMap.Internal provides a way to access its // owner (aka EObject) result.add(((FeatureMap.Internal) fm).getEObject() .eClass().getEPackage()); return result; } break; case Axis.ATTRIBUTE: if (nameTest == null || "*".equals(nameTest)) //$NON-NLS-1$ return getAllEAttributesContentAsList(fm); for (FeatureMap.Entry entry : fm) if (entry.getEStructuralFeature().getName().equals(nameTest) && entry.getEStructuralFeature() instanceof EAttribute) return getFeatureContentAsList(fm, entry.getEStructuralFeature()); break; case Axis.REFERENCE: { if (nameTest == null || "*".equals(nameTest)) //$NON-NLS-1$ return getAllEReferencesContentAsList(fm); for (FeatureMap.Entry entry : fm) if (entry.getEStructuralFeature().getName().equals(nameTest) && entry.getEStructuralFeature() instanceof EReference) return getFeatureContentAsList(fm, entry.getEStructuralFeature()); } break; case Axis.VARIABLE: { try { // TODO : not finished, the name of the method will change // only FeatureMap.Internal provides a way to access its // owner (aka EObject) if (!(fm instanceof FeatureMap.Internal)) return Collections.emptyList(); Object object = ((FeatureMap.Internal) fm).getEObject(); Method getValueMethod = object.getClass().getMethod( "get", new Class[] { String.class }); //$NON-NLS-1$ if (getValueMethod != null) { Object value = getValueMethod.invoke(object, new Object[] { nameTest }); if (value instanceof List) return (List<?>) value; else if (value instanceof Object) { List<Object> returnedAsList = new ArrayList<Object>(1); returnedAsList.add(value); return returnedAsList; } } } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { // Nothing to do here } catch (IllegalArgumentException e) { // Nothing to do here } catch (IllegalAccessException e) { e.printStackTrace(); // Nothing to do here } catch (InvocationTargetException e) { // Nothing to do here } } break; case Axis.SELF: if (nameTest == null) { List<Object> result = new ArrayList<Object>(1); result.add(fm); return result; } break; } return Collections.emptyList(); } private static List<EObject> getEContent(FeatureMap fm) { List<EObject> result = new ArrayList<EObject>(); for (FeatureMap.Entry entry : fm) { if (entry.getEStructuralFeature() instanceof EReference) { EReference ref = (EReference) entry.getEStructuralFeature(); if (ref.isContainment()) if (entry.getValue() instanceof EObject) { if (!result.contains(entry.getValue())) result.add((EObject) entry.getValue()); } else if (entry.getValue() instanceof List<?>) { for (Object item : (List<?>) entry.getValue()) if (item instanceof EObject && result.contains(item)) result.add((EObject) item); } } } return result; } @SuppressWarnings("unchecked") protected static List<?> getAllEAttributesContentAsList(FeatureMap fm) { List<Object> result = new ArrayList<Object>(); for (FeatureMap.Entry entry : fm) if (entry.getEStructuralFeature() instanceof EAttribute) { if (entry.getValue() instanceof List<?>) result.addAll((List<Object>) entry.getValue()); else result.add(entry.getValue()); } return result; } @SuppressWarnings("unchecked") protected static List<?> getAllEReferencesContentAsList(FeatureMap fm) { List<Object> result = new ArrayList<Object>(); for (FeatureMap.Entry entry : fm) if (entry.getEStructuralFeature() instanceof EReference) { if (entry.getValue() instanceof List<?>) result.addAll((List<Object>) entry.getValue()); else result.add(entry.getValue()); } return result; } protected static List<?> getFeatureContentAsList(FeatureMap fm, EStructuralFeature feature) { Object value = fm.get(feature, false); if (value instanceof List<?>) return (List<?>) value; else if (value instanceof Object) { List<Object> result = new ArrayList<Object>(1); result.add(value); return result; } return Collections.emptyList(); } }