001: /*
002: JSPWiki - a JSP-based WikiWiki clone.
003:
004: Copyright (C) 2001-2002 Janne Jalkanen (Janne.Jalkanen@iki.fi)
005:
006: This program is free software; you can redistribute it and/or modify
007: it under the terms of the GNU Lesser General Public License as published by
008: the Free Software Foundation; either version 2.1 of the License, or
009: (at your option) any later version.
010:
011: This program is distributed in the hope that it will be useful,
012: but WITHOUT ANY WARRANTY; without even the implied warranty of
013: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: GNU Lesser General Public License for more details.
015:
016: You should have received a copy of the GNU Lesser General Public License
017: along with this program; if not, write to the Free Software
018: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: */
020: package com.ecyrd.jspwiki.dav;
021:
022: import java.util.ArrayList;
023: import java.util.StringTokenizer;
024:
025: /**
026: * The DavPath represents an abstract path to any resource within the WebDav
027: * system. Since the file tree displayed by the DAV storage may be different
028: * from the actual representation, this component is needed.
029: * <p>
030: * You instantiate a new DavPath simply by saying
031: * <code>DavPath dp = new DavPath("/path/to/my/object");</code>
032: * <p>
033: * If the path ends in a slash, it is understood to be a directory. If not,
034: * it represents a file.
035: *
036: * @author jalkanen
037: *
038: */
039: public class DavPath {
040: private ArrayList m_parts = new ArrayList();
041:
042: private boolean m_isAbsolute = false;
043: private boolean m_isDirectory = false;
044:
045: /**
046: * Creates a new, empty path.
047: *
048: */
049: private DavPath() {
050: }
051:
052: /**
053: * Creates a new DavPath from an old one.
054: * @param dp the dav path
055: */
056: public DavPath(DavPath dp) {
057: m_parts.addAll(dp.m_parts);
058: m_isAbsolute = dp.m_isAbsolute;
059: m_isDirectory = dp.m_isDirectory;
060: }
061:
062: /**
063: * Creates a new DavPath object. The path parameter should be
064: * an arbitrary string with components separated with slashes.
065: * @param path
066: */
067: public DavPath(String path) {
068: if (path == null) {
069: m_isDirectory = true;
070: m_isAbsolute = true;
071: return;
072: }
073:
074: StringTokenizer st = new StringTokenizer(path, "/");
075:
076: while (st.hasMoreTokens()) {
077: String part = st.nextToken();
078:
079: //
080: // Skip empty components so that // gets transformed to a single /
081: //
082: if (part.length() > 0)
083: m_parts.add(part);
084: }
085:
086: //
087: // Figure out path attributes
088: //
089: if (path.endsWith("/"))
090: m_isDirectory = true;
091:
092: m_isAbsolute = path.startsWith("/");
093: }
094:
095: /**
096: * Adds another path to the end of this path.
097: *
098: * @param dp the current dav path
099: */
100: public void append(DavPath dp) {
101: m_parts.addAll(dp.m_parts);
102: m_isDirectory = dp.m_isDirectory;
103: }
104:
105: /**
106: * Adds another path to the end of this path. The "path" parameter
107: * may contain a slash-separated path (e.g. "foo/bar/blog.txt").
108: *
109: * @param path the current dav path
110: */
111: public void append(String path) {
112: DavPath dp = new DavPath(path);
113:
114: append(dp);
115: }
116:
117: /**
118: * Returns true, if the path represents the top-level entity. This is true,
119: * if the path is "/" or it is empty.
120: *
121: * @return True or false.
122: */
123: public boolean isRoot() {
124: return m_parts.size() == 0 || m_parts.get(0).equals("");
125: }
126:
127: /**
128: * Returns true, if the path represents a directory.
129: *
130: * @return <code>true</code> if the path is a directory; <code>false</code> otherwise
131: */
132: public boolean isDirectory() {
133: return isRoot() || m_isDirectory;
134: }
135:
136: /**
137: * Returns the directory part of the DavPath.
138: *
139: * @return the directory portion of the path
140: */
141: public String pathPart() {
142: StringBuffer result = new StringBuffer(m_isAbsolute ? "/" : "");
143:
144: for (int i = 0; i < m_parts.size() - (m_isDirectory ? 0 : 1); i++) {
145: result.append((String) m_parts.get(i));
146: result.append("/");
147: }
148:
149: return result.toString();
150: }
151:
152: /**
153: * Returns the file part of the DavPath. The method returns the last component
154: * of the path, unless the path is a directory, in which case it returns an
155: * empty string.
156: *
157: * @return the file name, or an empty string
158: */
159: public String filePart() {
160: if (m_parts.size() > 0 && !m_isDirectory)
161: return (String) m_parts.get(m_parts.size() - 1);
162:
163: return "";
164: }
165:
166: /**
167: * Returns the name of the last component of the DavPath. This is either
168: * the name of a directory, or the name of a file.
169: *
170: * @return the name of the right-most portion of the dav path
171: */
172: public String getName() {
173: if (isRoot())
174: return "/";
175: if (!isDirectory())
176: return filePart();
177:
178: return (String) m_parts.get(m_parts.size() - 1);
179: }
180:
181: /**
182: * Returns the entire path as a String.
183: * @return the entire dav path
184: */
185: public String getPath() {
186: return pathPart() + filePart();
187: }
188:
189: /**
190: * Returns a new DavPath object that is a sub-path of this path. E.g. if
191: * the path is "/foo/bar/blog.txt", subPath(1) would return "bar/blog.txt".
192: * Notice that the resulting path is not absolute in this case.
193: *
194: * @param idx Start from this part.
195: * @return A sub-path of this path.
196: */
197: public DavPath subPath(int idx) {
198: DavPath dp = new DavPath();
199:
200: for (int i = idx; i < m_parts.size(); i++) {
201: dp.m_parts.add(m_parts.get(i));
202: }
203:
204: // Only full copies are absolute paths
205: dp.m_isAbsolute = idx == 0;
206: dp.m_isDirectory = m_isDirectory;
207:
208: return dp;
209: }
210:
211: /**
212: * Returns the 'idx' component of the path, zero being the first component.
213: * If there is no such component,
214: * it will simply return null.
215: *
216: * @param idx The component to return. Zero is the first element.
217: * @return A part of the path.
218: */
219: public String get(int idx) {
220: if (idx > size())
221: return null;
222:
223: return (String) m_parts.get(idx);
224: }
225:
226: /**
227: * Exactly equivalent to length().
228: *
229: * @return The length of the path.
230: */
231: public int size() {
232: return m_parts.size();
233: }
234:
235: /**
236: * Exactly equivalent to size(). I'm too lazy to remember whether it's length() or size(),
237: * so I'll provide both...
238: *
239: * @return the size of the path
240: */
241: public int length() {
242: return m_parts.size();
243: }
244:
245: /**
246: * Returns a human-readable version of the path. Please use getPath() instead
247: * of toString(), as this method is only good for debugging purposes.
248: * @return the String representation of the path
249: */
250: public String toString() {
251: return "DavPath [" + getPath() + "]";
252: }
253: }
|