001 /* 002 * $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 $ 003 * $Revision: 155476 $ 004 * $Date: 2005-02-26 13:31:24 +0000 (Sat, 26 Feb 2005) $ 005 * 006 * ==================================================================== 007 * 008 * Copyright 2004 The Apache Software Foundation 009 * 010 * Licensed under the Apache License, Version 2.0 (the "License"); 011 * you may not use this file except in compliance with the License. 012 * You may obtain a copy of the License at 013 * 014 * http://www.apache.org/licenses/LICENSE-2.0 015 * 016 * Unless required by applicable law or agreed to in writing, software 017 * distributed under the License is distributed on an "AS IS" BASIS, 018 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 019 * See the License for the specific language governing permissions and 020 * limitations under the License. 021 * 022 */ 023 024 package org.apache.commons.xmlio.in; 025 026 import java.util.Collection; 027 import java.util.Iterator; 028 029 /** 030 * <b>Rudimentary</b> representation of a path to an XML element. 031 * <br> 032 * Two paths match in two cases: 033 * <ol><li>If they are really equal in terms of the {@link #equals} method. 034 * <li>If the path to match to is relative, i.e. it has no leading '/' and it is the suffix of the matching path. 035 * </ol> 036 * <br> 037 * For example<br> 038 * <code>/root/tag</code> matches <code>/root/tag</code> and<br> 039 * <code>/root/tag</code> matches <code>tag</code>. 040 * 041 */ 042 public class SimplePath { 043 044 protected final String path; 045 protected final Item[] pathList; 046 047 /** Strips off ending slash from a string if there is one. */ 048 public final static String stripEndingSlash(String path) { 049 if (path != null && path.length() > 0 && path.charAt(path.length() - 1) == '/') { 050 return path.substring(0, path.length() - 1); 051 } 052 return path; 053 } 054 055 /** Creates a path object from a string describing it. The describing 056 * string uses '/' characters to seperate the paths parts. 057 */ 058 public SimplePath(String path) { 059 this(path, null); 060 } 061 062 /** Creates a path object from a string describing it. The describing 063 * string uses '/' characters to seperate the paths parts. 064 */ 065 public SimplePath(String path, Item[] pathList) { 066 this.path = stripEndingSlash(path); 067 this.pathList = pathList; 068 } 069 070 /** Copy ctor. */ 071 public SimplePath(SimplePath path) { 072 this.path = stripEndingSlash(path.toString()); 073 this.pathList = new Item[path.pathList.length]; 074 System.arraycopy(path.pathList, 0, this.pathList, 0, path.pathList.length); 075 } 076 077 /** 078 * Checks if an item matches the last segment of this path. 079 */ 080 public boolean matches(Item name) { 081 return (pathList != null && pathList.length > 0 && pathList[pathList.length - 1].equals(name)); 082 } 083 084 /** 085 * Checks if the given array of items matches this path. 086 */ 087 public boolean matches(Item[] path, boolean isRelative) { 088 if (pathList == null 089 || path == null 090 || path.length > pathList.length 091 || (!isRelative && path.length != pathList.length)) { 092 return false; 093 } else { 094 for (int i = path.length - 1; i >= 0; i--) { 095 if (!pathList[i].equals(path[i])) { 096 return false; 097 } 098 } 099 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 }