001: /*
002: * Jacareto Copyright (c) 2002-2005
003: * Applied Computer Science Research Group, Darmstadt University of
004: * Technology, Institute of Mathematics & Computer Science,
005: * Ludwigsburg University of Education, and Computer Based
006: * Learning Research Group, Aachen University. All rights reserved.
007: *
008: * Jacareto is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU General Public
010: * License as published by the Free Software Foundation; either
011: * version 2 of the License, or (at your option) any later version.
012: *
013: * Jacareto is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * General Public License for more details.
017: *
018: * You should have received a copy of the GNU General Public
019: * License along with Jacareto; if not, write to the Free
020: * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
021: *
022: */
023:
024: package jacareto.filter;
025:
026: import jacareto.struct.Structure;
027: import jacareto.struct.StructureElement;
028: import jacareto.system.Environment;
029: import jacareto.system.EnvironmentMember;
030:
031: import java.util.Stack;
032: import java.util.Vector;
033:
034: /**
035: * A class which filters structures. The method {@link #getElements(Structure,boolean)} returns all
036: * structure elements contained in the structure for which the method {@link
037: * #matches(StructureElement)} returns <code>true</code>.
038: *
039: * @author <a href="mailto:cspannagel@web.de">Christian Spannagel</a>
040: * @version 1.0
041: */
042: public abstract class Filter extends EnvironmentMember {
043: /**
044: * Creates a new filter.
045: *
046: * @param env the environment
047: */
048: public Filter(Environment env) {
049: super (env);
050: }
051:
052: /**
053: * Returns <code>true</code> when a given structure elements matches the filter criterion,
054: * otherwise <code>false</code>.
055: *
056: * @param element DOCUMENT ME!
057: *
058: * @return DOCUMENT ME!
059: */
060: public abstract boolean matches(StructureElement element);
061:
062: /**
063: * Returns the name of the filter.
064: *
065: * @return DOCUMENT ME!
066: */
067: public abstract String getName();
068:
069: /**
070: * Returns all structure elements contained in the given structure for which the method {@link
071: * #matches(StructureElement)} returns <code>true</code>. If a structure element does not
072: * match the filter criterion, its children will be tested. If a structure element matches the
073: * criterion, its children will only be tested when the argument <code>recurseOnMatch</code>
074: * is set to <code>true</code>.
075: *
076: * @param structure the structure
077: * @param recurseOnMatch whether or not recursing into an element's children when the element
078: * matches a criterion
079: *
080: * @return the structure elements contained in the structure which match the filter criterion
081: */
082: public StructureElement[] getElements(Structure structure,
083: boolean recurseOnMatch) {
084: return getElements(structure.getRootElement(), recurseOnMatch);
085: }
086:
087: /**
088: * Returns all structure elements contained in the subtree of the given structure element for
089: * which the method {@link #matches(StructureElement)} returns <code>true</code>. If a
090: * structure element does not match the filter criterion, its children will be tested. If a
091: * structure element matches the criterion, its children will only be tested when the argument
092: * <code>recurseOnMatch</code> is set to <code>true</code>.
093: *
094: * @param element the structure element
095: * @param recurseOnMatch whether or not recursing into an element's children when the element
096: * matches a criterion
097: *
098: * @return the structure elements contained in the structure which match the filter criterion
099: */
100: public StructureElement[] getElements(StructureElement element,
101: boolean recurseOnMatch) {
102: Vector vResult = new Vector(10, 10);
103: StructureElement[] result;
104:
105: // initialize the stack
106: Stack stack = new Stack();
107: stack.push(element);
108:
109: while (!stack.isEmpty()) {
110: StructureElement el = (StructureElement) stack.pop();
111: boolean addChildren;
112:
113: if (matches(el)) {
114: vResult.add(el);
115: addChildren = recurseOnMatch && el.hasChildren();
116: } else {
117: addChildren = el.hasChildren();
118: }
119:
120: // add the structure element's children
121: if (addChildren) {
122: StructureElement[] children = el.getChildren();
123:
124: for (int i = children.length - 1; i >= 0; i--) {
125: stack.push(children[i]);
126: }
127: }
128: }
129:
130: result = new StructureElement[vResult.size()];
131:
132: for (int i = 0; i < result.length; i++) {
133: result[i] = (StructureElement) vResult.get(i);
134: }
135:
136: return result;
137: }
138:
139: /**
140: * Returns a string representation (the name of the filter)
141: *
142: * @return DOCUMENT ME!
143: */
144: public String toString() {
145: return getName();
146: }
147: }
|