View Javadoc

1   /*
2    * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons-sandbox//xmlio/src/java/org/apache/commons/xmlio/in/SimplePath.java,v 1.1 2004/10/08 11:56:20 ozeigermann Exp $
3    * $Revision: 155476 $
4    * $Date: 2005-02-26 13:31:24 +0000 (Sat, 26 Feb 2005) $
5    *
6    * ====================================================================
7    *
8    * Copyright 2004 The Apache Software Foundation 
9    *
10   * Licensed under the Apache License, Version 2.0 (the "License");
11   * you may not use this file except in compliance with the License.
12   * You may obtain a copy of the License at
13   *
14   *     http://www.apache.org/licenses/LICENSE-2.0
15   *
16   * Unless required by applicable law or agreed to in writing, software
17   * distributed under the License is distributed on an "AS IS" BASIS,
18   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19   * See the License for the specific language governing permissions and
20   * limitations under the License.
21   *
22   */
23  
24  package org.apache.commons.xmlio.in;
25  
26  import java.util.Collection;
27  import java.util.Iterator;
28  
29  /**
30   * <b>Rudimentary</b> representation of a path to an XML element. 
31   * <br>
32   * Two paths match in two cases:
33   * <ol><li>If they are really equal in terms of the {@link #equals} method.
34   * <li>If the path to match to is relative, i.e. it has no leading '/' and it is the suffix of the matching path.
35   * </ol>
36   * <br>
37   * For example<br>
38   * <code>/root/tag</code> matches <code>/root/tag</code> and<br>
39   * <code>/root/tag</code> matches <code>tag</code>.
40   *
41   */
42  public class SimplePath {
43  
44      protected final String path;
45      protected final Item[] pathList;
46  
47      /** Strips off ending slash from a string if there is one. */
48      public final static String stripEndingSlash(String path) {
49          if (path != null && path.length() > 0 && path.charAt(path.length() - 1) == '/') {
50              return path.substring(0, path.length() - 1);
51          }
52          return path;
53      }
54  
55      /** Creates a path object from a string describing it. The describing
56       * string uses '/' characters to seperate the paths parts.
57       */
58      public SimplePath(String path) {
59          this(path, null);
60      }
61  
62      /** Creates a path object from a string describing it. The describing
63       * string uses '/' characters to seperate the paths parts.
64       */
65      public SimplePath(String path, Item[] pathList) {
66          this.path = stripEndingSlash(path);
67          this.pathList = pathList;
68      }
69  
70      /** Copy ctor. */
71      public SimplePath(SimplePath path) {
72          this.path = stripEndingSlash(path.toString());
73          this.pathList = new Item[path.pathList.length];
74          System.arraycopy(path.pathList, 0, this.pathList, 0, path.pathList.length);
75      }
76  
77      /**
78       * Checks if an item matches the last segment of this path.
79       */
80      public boolean matches(Item name) {
81          return (pathList != null && pathList.length > 0 && pathList[pathList.length - 1].equals(name));
82      }
83  
84      /**
85       * Checks if the given array of items matches this path.
86       */
87      public boolean matches(Item[] path, boolean isRelative) {
88          if (pathList == null
89              || path == null
90              || path.length > pathList.length
91              || (!isRelative && path.length != pathList.length)) {
92              return false;
93          } else {
94              for (int i = path.length - 1; i >= 0; i--) {
95                  if (!pathList[i].equals(path[i])) {
96                      return false;
97                  }
98              }
99              return true;
100         }
101     }
102 
103     /**
104      * Checks if the given array of items matches this path from the root. The given path is to be considered relative.
105      * Useful to distinguish between something like /rootPath/valid/*\/valid and /rootPath/invalid/*\/valid. You will need two
106      * matches for this:
107      * <pre>
108      * matchesFromRoot(new Item[] { new Item("rootPath"), new Item("valid")}) 
109      * &&
110      * matches(new Item("valid"))
111      * </pre>
112      */
113     public boolean matchesFromRoot(Item[] path) {
114         if (pathList == null || path == null || path.length > pathList.length) {
115             return false;
116         } else {
117             for (int i = 0; i < path.length; i++) {
118                 if (!pathList[i].equals(path[i])) {
119                     return false;
120                 }
121             }
122             return true;
123         }
124     }
125 
126     /**
127      * Checks if the given array of items matches this path. The given path is to be considered relative.
128      */
129     public boolean matches(Item[] path) {
130         return matches(path, true);
131     }
132 
133     /** Finds out if the the given path matches this one. 
134      */
135     public boolean matches(SimplePath matchPath) {
136         return matches(matchPath.toString());
137     }
138 
139     /** Finds out if the path represented by the given string matches this one. 
140      * @see #matches(SimplePath)
141     */
142     public boolean matches(String matchPath) {
143         String matchString = stripEndingSlash(matchPath);
144 
145         if (matchString != null && matchString.length() > 0 && matchString.charAt(0) != '/') {
146             // relative
147             return path.endsWith("/" + matchString);
148         } else {
149             // absolute
150             return path.equals(matchString);
151         }
152     }
153 
154     /** Checks if this path matches any of the paths stored in
155      * <code>paths</code> collection. This means we iterate through 
156      * <code>paths</code> and match every entry to this path.
157      */
158     public boolean matchsAny(Collection paths) {
159         for (Iterator it = paths.iterator(); it.hasNext();) {
160             SimplePath matchPath = (SimplePath) it.next();
161             if (matches(matchPath))
162                 return true;
163         }
164         return false;
165     }
166 
167     /** Checks if this path matches any of the paths stored in
168      * <code>paths</code> collection. This means we iterate through 
169      * <code>paths</code> and match every entry to this path.
170      */
171     public boolean matchsAny(String[] paths) {
172         for (int i = 0; i < paths.length; i++) {
173             if (matches(paths[i]))
174                 return true;
175         }
176         return false;
177     }
178 
179     public String toString() {
180         return path;
181     }
182 
183     public boolean equals(Object o) {
184         if (o instanceof String) {
185             return path.equals(o);
186         } else if (o instanceof SimplePath) {
187             return path.equals(((SimplePath) o).toString());
188         } else {
189             return false;
190         }
191     }
192 
193 }