001/*
002 * Copyright 2001 (C) MetaStuff, Ltd. All Rights Reserved.
003 * 
004 * This software is open source. 
005 * See the bottom of this file for the licence.
006 * 
007 * $Id: Rule.java,v 1.2 2001/08/17 09:45:19 jstrachan Exp $
008 */
009
010package org.dom4j.rule;
011
012import org.dom4j.Node;
013
014/** <p><code>Rule</code> matches against DOM4J Node so that some action
015  * can be performed such as in the XSLT processing model.</p>
016  *
017  * @author <a href="mailto:james.strachan@metastuff.com">James Strachan</a>
018  * @version $Revision: 1.2 $
019  */
020public class Rule implements Comparable {
021
022    /** Holds value of property mode. */
023    private String mode;
024    
025    /** Holds value of property importPrecedence. */
026    private int importPrecedence;
027    
028    /** Holds value of property priority. */
029    private double priority;
030    
031    /** Holds value of property appearenceCount. */
032    private int appearenceCount;
033    
034    /** Holds value of property pattern. */
035    private Pattern pattern;    
036    
037    /** Holds value of property action. */
038    private Action action;
039    
040    public Rule() {
041        this.priority = Pattern.DEFAULT_PRIORITY;
042    }
043
044    public Rule( Pattern pattern ) {
045        this.pattern = pattern;
046        this.priority = pattern.getPriority();
047    }
048
049    public Rule( Pattern pattern, Action action ) {
050        this( pattern );
051        this.action = action;
052    }
053
054    /** Constructs a new Rule with the same instance data
055      * as the given rule but a different pattern.
056      */
057    public Rule(Rule that, Pattern pattern) {
058        this.mode = that.mode;
059        this.importPrecedence = that.importPrecedence;
060        this.priority = that.priority;
061        this.appearenceCount = that.appearenceCount;
062        this.action = that.action;
063        this.pattern = pattern;
064    }
065
066    public boolean equals(Object that) {
067        if ( that instanceof Rule ) {
068            return compareTo( (Rule) that ) == 0;
069        }
070        return false;
071    }
072    
073    public int compareTo(Object that) {
074        if ( that instanceof Rule ) {
075            return compareTo((Rule) that);
076        }
077        return getClass().getName().compareTo( that.getClass().getName() );
078    }
079    
080    /** Compares two rules in XSLT processing model order
081      * assuming that the modes are equal.
082      */
083    public int compareTo(Rule that) {
084        int answer = this.importPrecedence - that.importPrecedence;
085        if ( answer == 0 ) {
086            answer = (int) Math.round( this.priority - that.priority );
087            if ( answer == 0 ) {
088                answer = this.appearenceCount - that.appearenceCount;
089            }
090        }
091        return answer;
092    }
093    
094    public String toString() {
095        return super.toString() + "[ pattern: " + getPattern() + " action: " + getAction() + " ]";
096    }
097    
098    
099    
100    /** @return true if the pattern matches the given 
101      * DOM4J node.
102      */
103    public final boolean matches( Node node ) {
104        return pattern.matches( node );
105    }
106    
107    /** If this rule contains a union pattern then this
108      * method should return an array of Rules which
109      * describe the union rule, which should contain more than one rule.
110      * Otherwise this method should return null.
111      *
112      * @return an array of the rules which make up this union rule
113      * or null if this rule is not a union rule
114      */
115    public Rule[] getUnionRules() {
116        Pattern[] patterns = pattern.getUnionPatterns();
117        if ( patterns == null ) {
118            return null;
119        }
120        int size = patterns.length;
121        Rule[] answer = new Rule[ size ];
122        for ( int i = 0; i < size; i++ ) {
123            answer[i] = new Rule( this, patterns[i] );
124        }
125        return answer;
126    }
127
128    
129    /** @return the type of node the pattern matches
130      * which by default should return ANY_NODE if it can
131      * match any kind of node.
132      */
133    public final short getMatchType() {
134        return pattern.getMatchType();
135    }
136
137
138    /** For patterns which only match an ATTRIBUTE_NODE or an 
139      * ELEMENT_NODE then this pattern may return the name of the
140      * element or attribute it matches. This allows a more efficient
141      * rule matching algorithm to be performed, rather than a brute 
142      * force approach of evaluating every pattern for a given Node.
143      *
144      * @return the name of the element or attribute this pattern matches
145      * or null if this pattern matches any or more than one name.
146      */
147    public final String getMatchesNodeName() {
148        return pattern.getMatchesNodeName();
149    }
150    
151    
152    
153    
154    
155    /** Getter for property mode.
156     * @return Value of property mode.
157     */
158    public String getMode() {
159        return mode;
160    }
161    
162    /** Setter for property mode.
163     * @param mode New value of property mode.
164     */
165    public void setMode(String mode) {
166        this.mode = mode;
167    }
168    
169    /** Getter for property importPrecedence.
170     * @return Value of property importPrecedence.
171     */
172    public int getImportPrecedence() {
173        return importPrecedence;
174    }
175    
176    /** Setter for property importPrecedence.
177     * @param importPrecedence New value of property importPrecedence.
178     */
179    public void setImportPrecedence(int importPrecedence) {
180        this.importPrecedence = importPrecedence;
181    }
182    
183    /** Getter for property priority.
184     * @return Value of property priority.
185     */
186    public double getPriority() {
187        return priority;
188    }
189    
190    /** Setter for property priority.
191     * @param priority New value of property priority.
192     */
193    public void setPriority(double priority) {
194        this.priority = priority;
195    }
196    
197    /** Getter for property appearenceCount.
198     * @return Value of property appearenceCount.
199     */
200    public int getAppearenceCount() {
201        return appearenceCount;
202    }
203    
204    /** Setter for property appearenceCount.
205     * @param appearenceCount New value of property appearenceCount.
206     */
207    public void setAppearenceCount(int appearenceCount) {
208        this.appearenceCount = appearenceCount;
209    }
210    
211    /** Getter for property pattern.
212     * @return Value of property pattern.
213     */
214    public Pattern getPattern() {
215        return pattern;
216    }
217    
218    /** Setter for property pattern.
219     * @param pattern New value of property pattern.
220     */
221    public void setPattern(Pattern pattern) {
222        this.pattern = pattern;
223    }
224    
225    /** Getter for property action.
226     * @return Value of property action.
227     */
228    public Action getAction() {
229        return action;
230    }
231    
232    /** Setter for property action.
233     * @param action New value of property action.
234     */
235    public void setAction(Action action) {
236        this.action = action;
237    }
238    
239}
240
241
242
243
244/*
245 * Redistribution and use of this software and associated documentation
246 * ("Software"), with or without modification, are permitted provided
247 * that the following conditions are met:
248 *
249 * 1. Redistributions of source code must retain copyright
250 *    statements and notices.  Redistributions must also contain a
251 *    copy of this document.
252 *
253 * 2. Redistributions in binary form must reproduce the
254 *    above copyright notice, this list of conditions and the
255 *    following disclaimer in the documentation and/or other
256 *    materials provided with the distribution.
257 *
258 * 3. The name "DOM4J" must not be used to endorse or promote
259 *    products derived from this Software without prior written
260 *    permission of MetaStuff, Ltd.  For written permission,
261 *    please contact dom4j-info@metastuff.com.
262 *
263 * 4. Products derived from this Software may not be called "DOM4J"
264 *    nor may "DOM4J" appear in their names without prior written
265 *    permission of MetaStuff, Ltd. DOM4J is a registered
266 *    trademark of MetaStuff, Ltd.
267 *
268 * 5. Due credit should be given to the DOM4J Project
269 *    (http://dom4j.org/).
270 *
271 * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS
272 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
273 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
274 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
275 * METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
276 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
277 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
278 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
279 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
280 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
281 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
282 * OF THE POSSIBILITY OF SUCH DAMAGE.
283 *
284 * Copyright 2001 (C) MetaStuff, Ltd. All Rights Reserved.
285 *
286 * $Id: Rule.java,v 1.2 2001/08/17 09:45:19 jstrachan Exp $
287 */