/* * (C) Copyright IBM Corp. 2013 * * LICENSE: Eclipse Public License v1.0 * http://www.eclipse.org/legal/epl-v10.html */ package com.ibm.gaiandb.webservices.patternmatcher; import java.util.ArrayList; import com.ibm.gaiandb.webservices.scanner.Tag; /** * <p> * This class provides methods to manage TagMatcher objects. In this object, * two kind of methods can be distinguished: <br/> * - the configuration methods (getResult(), addMatcher(...), reinitializeResults(...)) <br/> * - The TagMatcher-objects-managing methods (getIn(...), getOut(...), getValue(...)) * <p> * Once the object has been set, the managing methods are going through all the * TagMatcher objects and call a specific method on all of them. Each TagMatcher will * then have their own behaviour. * * @author remi - IBM Hursley * * @see {@link TagMatcher} * */ public class MatcherManager extends ValueMatcher { // ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------- ATTRIBUTES // =========================================================================== Public // --------------------------------------------------------------------------- Static // Use PROPRIETARY notice if class contains a main() method, otherwise use // COPYRIGHT notice. public static final String COPYRIGHT_NOTICE = "(c) Copyright IBM Corp. 2013"; /** Value returned when the matcher has a result to return. */ public static final String GOT_RESULT = "GOT RESULT"; // -------------------------------------------------------------------------- Dynamic // ======================================================================== Protected // --------------------------------------------------------------------------- Static // -------------------------------------------------------------------------- Dynamic // ========================================================================== Private // --------------------------------------------------------------------------- Static // -------------------------------------------------------------------------- Dynamic /** All the TagMatchers that the object manages. */ private ArrayList<TagMatcher> matchers; /** * The number of TagMatcher objects the object will manage. This value is defined * when the object is created since the attribute result is a static array and will * be created in the object constructor. This avoids having to redefine the array * each time a TagMatcher is added to the object. */ protected int nbMatchers = 0; /** * The record the TagMatcher objects are filling. each TagMatcher will fill its own * cell in the array. The first TagMatcher fills the cell 0, the second TagMtcher * the cell 1... */ protected String[] results; // ---------------------------------------------------------------------------------- // ---------------------------------------------------------------------------- TOOLS // ---------------------------------------------------------------------------------- // -------------------------------------------------------------------------- METHODS // ===================================================================== Constructors // --------------------------------------------------------------------------- Public /** * Creates a MatcherManager object. * @param nbMatchersManagedToInsert * The number of matchers which will be inserted into the object. */ public MatcherManager(int nbMatchersManagedToInsert) { this(nbMatchersManagedToInsert, null); } public MatcherManager(int nbMatchersManagedToInsert, ArrayList<TagPattern> patterns) { super(patterns); this.matchers = new ArrayList<TagMatcher>(); // Once filled, this one won't change // this.visitedTags = new ArrayList<Tag>(); // This array will be filled and unfilled // as the scanner will go through a document this.nbMatchers = nbMatchersManagedToInsert; this.results = new String[this.nbMatchers]; } // -------------------------------------------------------------------------- Private // =========================================================================== Public // --------------------------------------------------------------------------- Static // -------------------------------------------------------------------------- Dynamic /** * TODO */ public ArrayList<TagMatcher> getMatchers() { return this.matchers; } /** * Adds a TagMatcher object to the object's list of TagMatcher. * @param matcher * The TagMatcher to add. */ public void addMatcher(TagMatcher matcher) { this.matchers.add(matcher); } /** * Sets the matchers. * @param matchers * The matchers to define as the */ public void setMatchers(ArrayList<TagMatcher> matchers) { this.matchers = matchers; } /** * Returns the set of results which have been read while going though the tags. * @return the set of results which have been read while going though the tags. */ public String[] getResult() { return this.results; } /** * Resets the records. Sets all the values at null. */ public void reinitializeResults() { this.results = new String[this.nbMatchers]; } /** * Go through all the TagMatcher added in the object and defines the common * root of them all. */ public void setCommonRoot() { for (TagMatcher matcher : this.matchers) { this.patternToMatch = this.defineCommonRoot( this.patternToMatch, matcher.patternToMatch); } } /** * Goes through all the TagMatcher objects of the current object and call * their method getIn(...) * * @param tag * The start element that the object using the MatcherManager * is scanning. * * @return null */ @Override public String getIn(Tag tag) { // warns all the matchers that it accesses to a new start element int matcherIndex = 0; for (TagMatcher matcher : this.matchers) { // And sets the new value returned by the the matcher if (matcher != null ) { String value = matcher.getIn(tag); if (value != null) { this.results[matcherIndex] = value; } } matcherIndex++; } super.getIn(tag); return null; } /** * Goes through all the TagMatcher objects of the current object and call * their method getOut(...) * * @param tagName * The name of the end element that the object using the * MatcherManager is scanning. * * @return null */ @Override public String getOut(String tagName) { int matcherIndex = 0; for (TagMatcher matcher : this.matchers) { if (matcher != null) { String value = matcher.getOut(tagName); if (value != null) { this.results[matcherIndex] = value; } } matcherIndex++; } String ret = super.getOut(tagName); if (ret != null) { return MatcherManager.GOT_RESULT; } return null; } /** * Goes through all the TagMatcher objects of the current object and call * their method getValue(...) * * @param value * The value that the object using the MatcherManager is scanning. * * @return null */ @Override public String getValue(String value) { int matcherIndex = 0; for (TagMatcher matcher : this.matchers) { if (matcher != null) { String resultsValue = matcher.getValue(value); if (resultsValue != null && !resultsValue.matches("\\s*")) { this.results[matcherIndex] = resultsValue; } } matcherIndex++; } if (value != null && !value.matches("\\s*")) { String ret = super.getValue(""); return ret; } return null; } // ======================================================================== Protected // --------------------------------------------------------------------------- Static // -------------------------------------------------------------------------- Dynamic // ========================================================================== Private // --------------------------------------------------------------------------- Static // -------------------------------------------------------------------------- Dynamic public void defineCommonRoot() { for (TagMatcher matcher : this.matchers) { this.patternToMatch = defineCommonRoot( this.patternToMatch, matcher.getPatternSequence()); } } /** * Defines the common root between two lists of TagPattern. Returns * a list of TagPattern objects containing this common root. The * TagPattern object only have names and no attribute or position. * If the parameters have a different root, returns an empty List. * * @param a1 * The first List. * @param a2 * YThe second List. * * @return a list of TagPattern objects containing this common root. * If the parameters have a different root, returns an empty List. * If one of the parameter is null, returns the other one (which can * also be null). */ private ArrayList<TagPattern> defineCommonRoot( ArrayList<TagPattern> a1, ArrayList<TagPattern> a2) { // ArrayList tto fill and return ArrayList<TagPattern> ret = new ArrayList<TagPattern>(); // If one is null, returns the other if (a1 == null || a1.isEmpty()) { return a2; } if (a2 == null || a2.isEmpty()) { return a1; } // Checks common root int minSize = a1.size(); int a2Size = a2.size(); if (minSize > a2Size) { minSize = a2Size; } for (int i = 0; i < minSize; i++) { String name1 = a1.get(i).getName(); String name2 = a2.get(i).getName(); // if a Jocker is found, store the name value of the other Tag. if (name1.equals(TagPattern.JOCKER_NAME)) { if (name2.equals(TagPattern.JOCKER_NAME)) { ret.add(TagPattern.JOCKER); } else { ret.add(new TagPattern(name2)); } } else if (name2.equals(TagPattern.JOCKER_NAME)) { ret.add(new TagPattern(name1)); } else if (name1.equals(name2)) { ret.add(new TagPattern(name1)); } else { return ret; } } return ret; } }