blob: f5808038a74394b7979a8137336d106fc6400100 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006 Oracle Corporation 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:
* Oracle Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.bpel.validator.model;
import java.util.ArrayList;
import java.util.List;
import javax.xml.namespace.QName;
/**
*
* @author Michal Chmielewski (michal.chmielewski@oracle.com)
* @date Sep 18, 2006
*
*/
@SuppressWarnings("nls")
public class Selector {
/** Selection of all nodes at a given level */
public static final String ALL = "*"; //$NON-NLS-1$
/**
* Brand new shiny selector.
*/
public Selector () {
}
/**
* Select the nodes according to the simple path specified.
*
* @param context
* @param segments
* @return the selected INode or null
*/
public INode selectNode ( INode context, Object ... segments ) {
List<INode> nodes = selectNodes ( context, segments );
return ( nodes.size() > 0 ? nodes.get(0) : null);
}
/**
* Select a parent node
* @param context
* @param filter
* @return the parent node that matches the filer
*/
public INode selectParent (INode context, IFilter<INode> filter) {
if (context == null) {
return context;
}
do {
if (filter.select(context)) {
return context;
}
context = context.parentNode();
} while (context != null);
return context;
}
/**
* Select the node given a context node according to the simple
* path specified. The path is a list of arguments that are either
* String or numbers.
*
* @param context
* @param segments
*
* @return the list of nodes that matches the selection.
*/
@SuppressWarnings("unchecked")
public List<INode> selectNodes ( INode context, Object ... segments ) {
List<INode> list = new ArrayList<INode>();
int n;
String s;
IFilter<INode> filter;
for (Object obj : segments) {
// if we ever don't have context, then we are done
if (context == null) {
break;
}
// filter just filters what's in the list so far
if (obj instanceof IFilter) {
filter = (IFilter<INode>) obj;
List<INode> newList = new ArrayList<INode>();
for(INode node : list ) {
if (filter.select(node)) {
newList.add(node);
}
}
list = newList;
context = list.size() > 0 ? (INode) list.get(0) : null;
} else if (obj instanceof String) {
list = selectNodesByName ( context, (String) obj );
context = list.size() > 0 ? (INode) list.get(0) : null;
} else if (obj instanceof QName) {
list = selectNodesByName ( context, (QName) obj );
context = list.size() > 0 ? (INode) list.get(0) : null;
} else if (obj instanceof Number) {
// selection of new context
n = ((Number)obj).intValue() - 1;
list.clear();
try {
context = list.get(n);
if (context != null) {
list.add ( context );
}
} catch (IndexOutOfBoundsException ioobe) {
context = null;
}
} else {
// no idea what I am doing.
list.clear();
context = null;
}
}
return list;
}
/**
* Select nodes by Name.
*
* @param context
* @param s
* @return a list of nodes matching the name
*/
List<INode> selectNodesByName ( INode context, QName s ) {
List<INode> list = new ArrayList<INode>();
if (s.getLocalPart().equals("..")) {
INode parent = context.parentNode();
if (parent != null) {
list.add(parent);
}
} else {
List<INode> children = context.children();
if (s.equals(ALL) ) {
list.addAll( children );
} else {
for(INode n : children) {
if (s.equals(n.nodeName())) {
list.add(n);
}
}
}
}
return list;
}
/**
* Select nodes by Name.
*
* @param context
* @param s
* @return a list of nodes matching the name
*/
List<INode> selectNodesByName ( INode context, String s ) {
List<INode> list = new ArrayList<INode>();
if (s.equals("..")) {
INode parent = context.parentNode();
if (parent != null) {
list.add(parent);
}
} else {
List<INode> children = context.children();
if (s.equals(ALL) ) {
list.addAll( children );
} else {
for(INode n : children) {
if (s.equals(n.nodeName().getLocalPart())) {
list.add(n);
}
}
}
}
return list;
}
}