/******************************************************************************* * Copyright (c) 2008 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.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import org.eclipse.emf.ecore.EObject; import org.eclipse.wazaabi.locationpaths.model.Axis; import org.eclipse.wazaabi.locationpaths.model.EMFPointer; import org.eclipse.wazaabi.locationpaths.model.JavaObjectPointer; import org.eclipse.wazaabi.locationpaths.model.LocationPath; import org.eclipse.wazaabi.locationpaths.model.Pointer; import org.eclipse.wazaabi.locationpaths.model.Step; public class LocationSelector { /** * Returns a list of <code>Pointer</code>s built by walking a path from the * context. * * @param context * The starting Pointer where to apply the steps. * @param path * The path to apply. * * @return A list of <code>Pointer</code>s. * * @see Pointer */ public static List<Pointer<?>> select(Object context, String locationPath) { LocationPath parsedPath = LocationParser.parse(locationPath); return select(context, parsedPath); } /** * Returns a list of <code>Pointer</code>s built by applying a * <code>LocationPath</code> onto the context. * * @param context * The starting Pointer where to apply the steps. * @param path * A <code>LocationPath</code> * * @return A list of <code>Pointer</code>s. * * @see LocationPath * @see Pointer */ public static List<Pointer<?>> select(Object context, LocationPath path) { if (path == null) return Collections.emptyList(); if (path.getInitialContext() != null) return select(createPointer((EObject) path.getInitialContext() .resolveContext()), path.getSteps()); return select(createPointer(context), path.getSteps()); } /** * Returns a list of <code>Pointer</code>s built by applying a list of * <code>Step</code>s onto the context. * * @param context * The starting Pointer where to apply the steps. * @param steps * A list of <code>Step</code>s. * * @return A list of <code>Pointer</code>s. * * @see Step * @see Pointer */ protected static List<Pointer<?>> select(Pointer<?> context, List<Step> steps) { if (context == null) return Collections.emptyList(); List<Object> contextChildren = new ArrayList<Object>(1); contextChildren.add(context.getContext()); for (int i = 0; i < steps.size() - 1; i++) { Step step = steps.get(i); List<Object> stepChildren = new ArrayList<Object>( contextChildren.size() * 3); Iterator<?> contextChildrenIterator = contextChildren.iterator(); while (contextChildrenIterator.hasNext()) { Object contextChild = contextChildrenIterator.next(); Iterator returnedStepChildrenIterator = Evaluator.evaluate( contextChild, step).iterator(); while (returnedStepChildrenIterator.hasNext()) { Object stepChild = returnedStepChildrenIterator.next(); if (!stepChildren.contains(stepChild)) stepChildren.add(stepChild); } } contextChildren = stepChildren; } List<Pointer<?>> result = new ArrayList<Pointer<?>>( contextChildren.size()); if (steps.isEmpty()) { result.add(context); return result; } Step step = steps.get(steps.size() - 1); Iterator contextChildrenIterator = contextChildren.iterator(); while (contextChildrenIterator.hasNext()) { Object contextChild = contextChildrenIterator.next(); List returnedStepChildren = Collections.emptyList(); if (Axis.ATTRIBUTE != step.getAxis() && Axis.REFERENCE != step.getAxis()) returnedStepChildren = Evaluator.evaluate(contextChild, step); if (returnedStepChildren.isEmpty()) { Pointer pointer = createPointer(contextChild, step); if (pointer != null && !result.contains(pointer)) result.add(pointer); } else { Iterator returnedStepChildrenIterator = returnedStepChildren .iterator(); while (returnedStepChildrenIterator.hasNext()) { Object value = returnedStepChildrenIterator.next(); Pointer<?> pointer = createPointer(value); // TODO : don't know what to do in this case if (pointer != null && !result.contains(pointer)) result.add(pointer); } } } return result; } private static Pointer<?> createPointer(Object context, Step step) { if (step == null) return createPointer(context); Pointer<?> pointer = null; if (context instanceof EObject) { pointer = new EMFPointer(); ((EMFPointer) pointer).setContext((EObject) context); } else if (context != null) { pointer = new JavaObjectPointer(); ((JavaObjectPointer) pointer).setContext(context); } if (pointer != null) pointer.setStep(step); return pointer; } private static Pointer<?> createPointer(Object context) { Step step = new Step(); // TODO merge with existing SELF_STEP creation tool step.setAxis(Axis.SELF); return createPointer(context, step); } }