You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@archiva.apache.org by br...@apache.org on 2008/03/13 19:28:50 UTC
svn commit: r636822 [4/9] - in /maven/archiva/branches/springy: ./
archiva-base/archiva-common/
archiva-base/archiva-consumers/archiva-database-consumers/src/test/java/org/apache/maven/archiva/consumers/database/
archiva-base/archiva-consumers/archiva-...
Added: maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/util/location/Parameters.java
URL: http://svn.apache.org/viewvc/maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/util/location/Parameters.java?rev=636822&view=auto
==============================================================================
--- maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/util/location/Parameters.java (added)
+++ maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/util/location/Parameters.java Thu Mar 13 11:28:26 2008
@@ -0,0 +1,474 @@
+/* ========================================================================== *
+ * Copyright (C) 2004-2006, Pier Fumagalli <http://could.it/> *
+ * All rights reserved. *
+ * ========================================================================== *
+ * *
+ * Licensed under the Apache License, Version 2.0 (the "License"). You may *
+ * not use this file except in compliance with the License. You may obtain a *
+ * copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>. *
+ * *
+ * Unless required by applicable law or agreed to in writing, software *
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT *
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the *
+ * License for the specific language governing permissions and limitations *
+ * under the License. *
+ * *
+ * ========================================================================== */
+package it.could.util.location;
+
+import it.could.util.StringTools;
+import it.could.util.encoding.Encodable;
+import it.could.util.encoding.EncodingTools;
+
+import java.io.UnsupportedEncodingException;
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+
+/**
+ * <p>The {@link Parameters Parameters} class represents a never empty and
+ * immutable {@link List} of {@link Parameters.Parameter Parameter} instances,
+ * normally created parsing a query string.</p>
+ *
+ * @author <a href="http://could.it/">Pier Fumagalli</a>
+ */
+public class Parameters extends AbstractList implements Encodable {
+
+ /** <p>The default delimiter for a {@link Parameters} instance.</p> */
+ public static final char DEFAULT_DELIMITER = '&';
+
+ /** <p>All the {@link Parameter}s in order.</p> */
+ private final Parameter parameters[];
+ /** <p>The {@link Map} view over all parameters (names are keys).</p> */
+ private final Map map;
+ /** <p>The {@link Set} of all parameter names.</p> */
+ final Set names;
+ /** <p>The character delimiting different parameters.</p> */
+ private final char delimiter;
+ /** <p>The encoded {@link String} representation of this.</p> */
+ private final String string;
+
+ /**
+ * <p>Create a new {@link Parameters Parameters} instance from
+ * a {@link List} of {@link Parameters.Parameter Parameter} instances
+ * using the {@link #DEFAULT_DELIMITER default parameter delimiter}.</p>
+ *
+ * @throws NullPointerExceptoin if the {@link List} was <b>null</b>.
+ * @throws IllegalArgumentException if the {@link List} was empty.
+ * @throws ClassCastException if any of the elements in the {@link List} was
+ * not a {@link Parameters.Parameter Parameter}.
+ */
+ public Parameters(List parameters) {
+ this(parameters, DEFAULT_DELIMITER);
+ }
+
+ /**
+ * <p>Create a new {@link Parameters Parameters} instance from
+ * a {@link List} of {@link Parameters.Parameter Parameter} instances
+ * using the specified character as the parameters delimiter.</p>
+ *
+ * @throws NullPointerExceptoin if the {@link List} was <b>null</b>.
+ * @throws IllegalArgumentException if the {@link List} was empty.
+ * @throws ClassCastException if any of the elements in the {@link List} was
+ * not a {@link Parameters.Parameter Parameter}.
+ */
+ public Parameters(List parameters, char delimiter) {
+ if (parameters.size() == 0) throw new IllegalArgumentException();
+ final Parameter array[] = new Parameter[parameters.size()];
+ final Map map = new HashMap();
+ for (int x = 0; x < array.length; x ++) {
+ final Parameter parameter = (Parameter) parameters.get(x);
+ final String key = parameter.getName();
+ List values = (List) map.get(key);
+ if (values == null) {
+ values = new ArrayList();
+ map.put(key, values);
+ }
+ values.add(parameter.getValue());
+ array[x] = parameter;
+ }
+
+ /* Make all parameter value lists unmodifiable */
+ for (Iterator iter = map.entrySet().iterator(); iter.hasNext(); ) {
+ final Map.Entry entry = (Map.Entry) iter.next();
+ final List list = (List) entry.getValue();
+ entry.setValue(Collections.unmodifiableList(list));
+ }
+
+ /* Store the current values */
+ this.delimiter = delimiter;
+ this.map = Collections.unmodifiableMap(map);
+ this.names = Collections.unmodifiableSet(map.keySet());
+ this.parameters = array;
+ this.string = EncodingTools.toString(this);
+ }
+
+ /* ====================================================================== */
+ /* STATIC CONSTRUCTION METHODS */
+ /* ====================================================================== */
+
+ /**
+ * <p>Utility method to create a new {@link Parameters} instance from a
+ * {@link List} of {@link Parameters.Parameter Parameter} instances.</p>
+ *
+ * @return a <b>non-null</b> and not empty {@link Parameters} instance or
+ * <b>null</b> if the specified {@link List} was <b>null</b>, empty
+ * or did not contain any {@link Parameters.Parameter Parameter}.
+ * @throws ClassCastException if any of the elements in the {@link List} was
+ * not a {@link Parameters.Parameter Parameter}.
+ */
+ public static Parameters create(List parameters) {
+ return create(parameters, DEFAULT_DELIMITER);
+ }
+
+ /**
+ * <p>Utility method to create a new {@link Parameters} instance from a
+ * {@link List} of {@link Parameters.Parameter Parameter} instances.</p>
+ *
+ * @return a <b>non-null</b> and not empty {@link Parameters} instance or
+ * <b>null</b> if the specified {@link List} was <b>null</b>, empty
+ * or did not contain any {@link Parameters.Parameter Parameter}.
+ * @throws ClassCastException if any of the elements in the {@link List} was
+ * not a {@link Parameters.Parameter Parameter}.
+ */
+ public static Parameters create(List parameters, char delimiter) {
+ if (parameters == null) return null;
+ final List dedupes = new ArrayList();
+ for (Iterator iter = parameters.iterator(); iter.hasNext(); ) {
+ Object next = iter.next();
+ if (dedupes.contains(next)) continue;
+ dedupes.add(next);
+ }
+ if (dedupes.size() == 0) return null;
+ return new Parameters(dedupes, delimiter);
+ }
+
+ /**
+ * <p>Parse the specified parameters {@link String} into a
+ * {@link Parameters} instance using the {@link #DEFAULT_DELIMITER default
+ * parameter delimiter}.</p>
+ *
+ * @return a <b>non-null</b> and not empty {@link Parameters} instance or
+ * <b>null</b> if the specified string was <b>null</b>, empty or
+ * did not contain any {@link Parameters.Parameter Parameter}.
+ */
+ public static Parameters parse(String parameters) {
+ try {
+ return parse(parameters, DEFAULT_DELIMITER, DEFAULT_ENCODING);
+ } catch (UnsupportedEncodingException exception) {
+ final String message = "Unsupported encoding " + DEFAULT_ENCODING;
+ final InternalError error = new InternalError(message);
+ throw (InternalError) error.initCause(exception);
+ }
+ }
+
+ /**
+ * <p>Parse the specified parameters {@link String} into a
+ * {@link Parameters} instance using the specified character as the
+ * parameters delimiter.</p>
+ *
+ * @return a <b>non-null</b> and not empty {@link Parameters} instance or
+ * <b>null</b> if the specified string was <b>null</b>, empty or
+ * did not contain any {@link Parameters.Parameter Parameter}.
+ */
+ public static Parameters parse(String parameters, char delimiter) {
+ try {
+ return parse(parameters, delimiter, DEFAULT_ENCODING);
+ } catch (UnsupportedEncodingException exception) {
+ final String message = "Unsupported encoding " + DEFAULT_ENCODING;
+ final InternalError error = new InternalError(message);
+ throw (InternalError) error.initCause(exception);
+ }
+ }
+
+ /**
+ * <p>Parse the specified parameters {@link String} into a
+ * {@link Parameters} instance using the {@link #DEFAULT_DELIMITER default
+ * parameter delimiter}.</p>
+ *
+ * @return a <b>non-null</b> and not empty {@link Parameters} instance or
+ * <b>null</b> if the specified string was <b>null</b>, empty or
+ * did not contain any {@link Parameters.Parameter Parameter}.
+ */
+ public static Parameters parse(String parameters, String encoding)
+ throws UnsupportedEncodingException {
+ return parse(parameters, DEFAULT_DELIMITER, encoding);
+ }
+
+ /**
+ * <p>Parse the specified parameters {@link String} into a
+ * {@link Parameters} instance using the specified character as the
+ * parameters delimiter.</p>
+ *
+ * @return a <b>non-null</b> and not empty {@link Parameters} instance or
+ * <b>null</b> if the specified string was <b>null</b>, empty or
+ * did not contain any {@link Parameters.Parameter Parameter}.
+ */
+ public static Parameters parse(String parameters, char delimiter,
+ String encoding)
+ throws UnsupportedEncodingException {
+ if (parameters == null) return null;
+ if (parameters.length() == 0) return null;
+ if (encoding == null) encoding = DEFAULT_ENCODING;
+ final String split[] = StringTools.splitAll(parameters, delimiter);
+ final List list = new ArrayList();
+ for (int x = 0; x < split.length; x ++) {
+ if (split[x] == null) continue;
+ if (split[x].length() == 0) continue;
+ Parameter parameter = Parameter.parse(split[x], encoding);
+ if (parameter != null) list.add(parameter);
+ }
+ if (list.size() == 0) return null;
+ return new Parameters(list, delimiter);
+ }
+
+ /* ====================================================================== */
+ /* PUBLIC EXPOSED METHODS */
+ /* ====================================================================== */
+
+ /**
+ * <p>Return the number of {@link Parameters.Parameter Parameter}s
+ * contained by this instance.</p>
+ */
+ public int size() {
+ return this.parameters.length;
+ }
+
+ /**
+ * <p>Return the {@link Parameters.Parameter Parameter} stored by this\
+ * instance at the specified index.</p>
+ */
+ public Object get(int index) {
+ return this.parameters[index];
+ }
+
+ /**
+ * <p>Return an immutable {@link Set} of {@link String}s containing all
+ * known {@link Parameters.Parameter Parameter}
+ * {@link Parameters.Parameter#getName() names}.</p>
+ */
+ public Set getNames() {
+ return this.names;
+ }
+
+ /**
+ * <p>Return the first {@link String} value associated with the
+ * specified parameter name, or <b>null</b>.</p>
+ */
+ public String getValue(String name) {
+ final List values = (List) this.map.get(name);
+ return values == null ? null : (String) values.get(0);
+ }
+
+ /**
+ * <p>Return an immutable {@link List} of all {@link String} values
+ * associated with the specified parameter name, or <b>null</b>.</p>
+ */
+ public List getValues(String name) {
+ return (List) this.map.get(name);
+ }
+
+ /* ====================================================================== */
+ /* OBJECT METHODS */
+ /* ====================================================================== */
+
+ /**
+ * <p>Return the URL-encoded {@link String} representation of this
+ * {@link Parameters Parameters} instance.</p>
+ */
+ public String toString() {
+ return this.string;
+ }
+
+ /**
+ * <p>Return the URL-encoded {@link String} representation of this
+ * {@link Parameters Parameters} instance using the specified
+ * character encoding.</p>
+ */
+ public String toString(String encoding)
+ throws UnsupportedEncodingException {
+ StringBuffer buffer = new StringBuffer();
+ for (int x = 0; x < this.parameters.length; x ++) {
+ buffer.append(this.delimiter);
+ buffer.append(this.parameters[x].toString(encoding));
+ }
+ return buffer.substring(1);
+ }
+
+ /**
+ * <p>Return the hash code value of this
+ * {@link Parameters Parameters} instance.</p>
+ */
+ public int hashCode() {
+ return this.string.hashCode();
+ }
+
+ /**
+ * <p>Check if the specified {@link Object} is equal to this
+ * {@link Parameters Parameters} instance.</p>
+ *
+ * <p>The specified {@link Object} is considered equal to this one if
+ * it is <b>non-null</b>, it is a {@link Parameters Parameters}
+ * instance, and its {@link #toString() string representation} equals
+ * this one's.</p>
+ */
+ public boolean equals(Object object) {
+ if ((object != null) && (object instanceof Parameters)) {
+ return this.string.equals(((Parameters) object).string);
+ } else {
+ return false;
+ }
+ }
+
+ /* ====================================================================== */
+ /* PUBLIC INNER CLASSES */
+ /* ====================================================================== */
+
+ /**
+ * <p>The {@link Parameters.Parameter Parameter} class represents a single
+ * parameter either parsed from a query string or a path element.</p>
+ *
+ * @author <a href="http://could.it/">Pier Fumagalli</a>
+ */
+ public static class Parameter implements Encodable {
+ /** <p>The name of the parameter (decoded).</p> */
+ private final String name;
+ /** <p>The value of the parameter (decoded).</p> */
+ private final String value;
+ /** <p>The encoded {@link String} representation of this.</p> */
+ private final String string;
+
+ /**
+ * <p>Create a new {@link Parameters.Parameter Parameter} given an
+ * encoded parameter name and value.</p>
+ *
+ * @throws NullPointerException if the name was <b>null</b>.
+ * @throws IllegalArgumentException if the name was an empty string.
+ */
+ public Parameter(String name, String value) {
+ if (name == null) throw new NullPointerException();
+ if (name.length() == 0) throw new IllegalArgumentException();
+ this.name = name;
+ this.value = value;
+ this.string = EncodingTools.toString(this);
+ }
+
+ /* ================================================================== */
+ /* STATIC CONSTRUCTION METHODS */
+ /* ================================================================== */
+
+ /**
+ * <p>Parse the specified parameters {@link String} into a
+ * {@link Parameters.Parameter} instance.</p>
+ *
+ * @return a <b>non-null</b> and not empty {@link Parameters.Parameter}
+ * instance or <b>null</b> if the specified string was
+ * <b>null</b> or empty.
+ */
+ public static Parameter parse(String parameter)
+ throws UnsupportedEncodingException {
+ try {
+ return parse(parameter, DEFAULT_ENCODING);
+ } catch (UnsupportedEncodingException exception) {
+ final String message = "Unsupported encoding " + DEFAULT_ENCODING;
+ final InternalError error = new InternalError(message);
+ throw (InternalError) error.initCause(exception);
+ }
+ }
+
+ /**
+ * <p>Parse the specified parameters {@link String} into a
+ * {@link Parameters.Parameter} instance.</p>
+ *
+ * @return a <b>non-null</b> and not empty {@link Parameters.Parameter}
+ * instance or <b>null</b> if the specified string was
+ * <b>null</b> or empty.
+ */
+ public static Parameter parse(String parameter, String encoding)
+ throws UnsupportedEncodingException {
+ if (parameter == null) return null;
+ if (encoding == null) encoding = DEFAULT_ENCODING;
+ String split[] = StringTools.splitOnce(parameter, '=', false);
+ if (split[0] == null) return null;
+ return new Parameter(split[0], split[1]);
+ }
+
+ /* ================================================================== */
+ /* PUBLIC EXPOSED METHODS */
+ /* ================================================================== */
+
+ /**
+ * <p>Return the URL-decoded name of this
+ * {@link Parameters.Parameter Parameter} instance.</p>
+ */
+ public String getName() {
+ return this.name;
+ }
+
+ /**
+ * <p>Return the URL-decoded value of this
+ * {@link Parameters.Parameter Parameter} instance.</p>
+ */
+ public String getValue() {
+ return this.value;
+ }
+
+ /* ================================================================== */
+ /* OBJECT METHODS */
+ /* ================================================================== */
+
+ /**
+ * <p>Return the URL-encoded {@link String} representation of this
+ * {@link Parameters.Parameter Parameter} instance.</p>
+ */
+ public String toString() {
+ return this.string;
+ }
+
+ /**
+ * <p>Return the URL-encoded {@link String} representation of this
+ * {@link Parameters.Parameter Parameter} instance using the specified
+ * character encoding.</p>
+ */
+ public String toString(String encoding)
+ throws UnsupportedEncodingException {
+ if (this.value != null) {
+ return EncodingTools.urlEncode(this.name, encoding) + "=" +
+ EncodingTools.urlEncode(this.value, encoding);
+ } else {
+ return EncodingTools.urlEncode(this.name, encoding);
+ }
+ }
+
+ /**
+ * <p>Return the hash code value for this
+ * {@link Parameters.Parameter Parameter} instance.</p>
+ */
+ public int hashCode() {
+ return this.string.hashCode();
+ }
+
+ /**
+ * <p>Check if the specified {@link Object} is equal to this
+ * {@link Parameters.Parameter Parameter} instance.</p>
+ *
+ * <p>The specified {@link Object} is considered equal to this one if
+ * it is <b>non-null</b>, it is a {@link Parameters.Parameter Parameter}
+ * instance, and its {@link #toString() string representation} equals
+ * this one's.</p>
+ */
+ public boolean equals(Object object) {
+ if ((object != null) && (object instanceof Parameter)) {
+ return this.string.equals(((Parameter) object).string);
+ } else {
+ return false;
+ }
+ }
+ }
+}
\ No newline at end of file
Propchange: maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/util/location/Parameters.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/util/location/Path.java
URL: http://svn.apache.org/viewvc/maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/util/location/Path.java?rev=636822&view=auto
==============================================================================
--- maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/util/location/Path.java (added)
+++ maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/util/location/Path.java Thu Mar 13 11:28:26 2008
@@ -0,0 +1,559 @@
+/* ========================================================================== *
+ * Copyright (C) 2004-2006, Pier Fumagalli <http://could.it/> *
+ * All rights reserved. *
+ * ========================================================================== *
+ * *
+ * Licensed under the Apache License, Version 2.0 (the "License"). You may *
+ * not use this file except in compliance with the License. You may obtain a *
+ * copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>. *
+ * *
+ * Unless required by applicable law or agreed to in writing, software *
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT *
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the *
+ * License for the specific language governing permissions and limitations *
+ * under the License. *
+ * *
+ * ========================================================================== */
+package it.could.util.location;
+
+import it.could.util.StringTools;
+import it.could.util.encoding.Encodable;
+import it.could.util.encoding.EncodingTools;
+
+import java.io.UnsupportedEncodingException;
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Stack;
+
+
+/**
+ * <p>The {@link Path Path} class is an ordered collection of
+ * {@link Path.Element Element} instances representing a path
+ * structure.</p>
+ *
+ * @author <a href="http://could.it/">Pier Fumagalli</a>
+ */
+public class Path extends AbstractList implements Encodable {
+
+ /** <p>The array of {@link Path.Element Element}s.</p> */
+ private final Element paths[];
+ /** <p>The current {@link Parameters} instance or <b>null</b>.</p> */
+ private final Parameters parameters;
+ /** <p>A flag indicating whether this path is absolute or not.</p> */
+ private final boolean absolute;
+ /** <p>A flag indicating if this path is a collection or not.</p> */
+ private final boolean collection;
+ /** <p>The {@link String} representation of this (encoded).</p> */
+ private final String string;
+
+ /**
+ * <p>Create a new {@link Path Path} instance.</p>
+ *
+ * @throws ClassCastException if any of the elements in the {@link List}
+ * was not a {@link Path.Element Element}.
+ */
+ public Path(List elements, boolean absolute, boolean collection) {
+ this(elements, absolute, collection, null);
+ }
+
+ /**
+ * <p>Create a new {@link Path Path} instance.</p>
+ *
+ * @throws ClassCastException if any of the elements in the {@link List}
+ * was not a {@link Path.Element Element}.
+ */
+ public Path(List elements, boolean absolute, boolean collection,
+ Parameters parameters) {
+ final Stack resolved = resolve(null, absolute, elements);
+ final Element array[] = new Element[resolved.size()];
+ this.paths = (Element []) resolved.toArray(array);
+ this.parameters = parameters;
+ this.absolute = absolute;
+ this.collection = collection;
+ this.string = EncodingTools.toString(this);
+ }
+
+ /* ====================================================================== */
+ /* STATIC CONSTRUCTION METHODS */
+ /* ====================================================================== */
+
+ /**
+ * <p>Parse the specified {@link String} into a {@link Path} structure.</p>
+ */
+ public static Path parse(String path) {
+ try {
+ return parse(path, DEFAULT_ENCODING);
+ } catch (UnsupportedEncodingException exception) {
+ final String message = "Unsupported encoding " + DEFAULT_ENCODING;
+ final InternalError error = new InternalError(message);
+ throw (InternalError) error.initCause(exception);
+ }
+ }
+
+ /**
+ * <p>Parse the specified {@link String} into a {@link Path} structure.</p>
+ */
+ public static Path parse(String path, String encoding)
+ throws UnsupportedEncodingException {
+ final List params = new ArrayList();
+ final List elems = new ArrayList();
+
+ /* No path, flog it! */
+ if ((path == null) || (path.length() == 0)) {
+ return new Path(elems, false, false, null);
+ }
+
+ /* Check for a proper encoding */
+ if (encoding == null) encoding = DEFAULT_ENCODING;
+
+ /* Split up the path structure into its path element components */
+ final String split[] = StringTools.splitAll(path, '/');
+
+ /* Check if this path is an absolute path */
+ final boolean absolute = path.charAt(0) == '/';
+
+ /* Check every single path element and append it to the current one */
+ Element element = null;
+ for (int x = 0; x < split.length; x++) {
+ if (split[x] == null) continue; /* Collapse double slashes */
+ element = parsePath(split[x], params, encoding);
+ if (element != null) elems.add(element);
+ }
+
+ /* Check if this is a collection */
+ final boolean collection = ((split[split.length - 1] == null)
+ || (element == null)
+ || element.getName().equals(".")
+ || element.getName().equals(".."));
+
+ /* Setup the last path in our chain and return the first one */
+ final Parameters parameters = Parameters.create(params, ';');
+ return new Path(elems, absolute, collection, parameters);
+ }
+
+ /* ====================================================================== */
+
+ /**
+ * <p>Parse a single path element like <code>path!extra;param</code>.</p>
+ */
+ private static Element parsePath(String path, List parameters,
+ String encoding)
+ throws UnsupportedEncodingException {
+ final int pathEnds = StringTools.findFirst(path, "!;");
+ final Element element;
+
+ if (pathEnds < 0) {
+ element = new Element(EncodingTools.urlDecode(path, encoding), null);
+ } else if (path.charAt(pathEnds) == ';') {
+ // --> pathname;pathparameter
+ final String name = path.substring(0, pathEnds);
+ final String param = path.substring(pathEnds + 1);
+ final Parameters params = Parameters.parse(param, ';', encoding);
+ if (params != null) parameters.addAll(params);
+ element = new Element(EncodingTools.urlDecode(name, encoding), null);
+ } else {
+ // --> pathname!extra...
+ final String name = path.substring(0, pathEnds);
+ final String more = path.substring(pathEnds + 1);
+ final String split[] = StringTools.splitOnce(more, ';', false);
+ final Parameters params = Parameters.parse(split[1], ';', encoding);
+ if (params != null) parameters.addAll(params);
+ element = new Element(EncodingTools.urlDecode(name, encoding),
+ EncodingTools.urlDecode(split[0], encoding));
+ }
+ if (element.toString().length() == 0) return null;
+ return element;
+ }
+
+ /* ====================================================================== */
+ /* RESOLUTION METHODS */
+ /* ====================================================================== */
+
+ /**
+ * <p>Resolve the specified {@link Path} against this one.</p>
+ */
+ public Path resolve(Path path) {
+ /* Merge the parameters */
+ final List params = new ArrayList();
+ if (this.parameters != null) params.addAll(this.parameters);
+ if (path.parameters != null) params.addAll(path.parameters);
+ final Parameters parameters = Parameters.create(params, ';');
+
+ /* No path, return this instance */
+ if (path == null) return this;
+
+ /* If the target is absolute, only merge the parameters */
+ if (path.absolute)
+ return new Path(path, true, path.collection, parameters);
+
+ /* Resolve the path */
+ final Stack source = new Stack();
+ source.addAll(this);
+ if (! this.collection && (source.size() > 0)) source.pop();
+ final List resolved = resolve(source, this.absolute, path);
+
+ /* Figure out if the resolved path is a collection and return it */
+ final boolean c = path.size() == 0 ? this.collection : path.collection;
+ return new Path(resolved, this.absolute, c, parameters);
+ }
+
+ /**
+ * <p>Parse the specified {@link String} into a {@link Path} and resolve it
+ * against this one.</p>
+ */
+ public Path resolve(String path) {
+ try {
+ return this.resolve(parse(path, DEFAULT_ENCODING));
+ } catch (UnsupportedEncodingException exception) {
+ final String message = "Unsupported encoding " + DEFAULT_ENCODING;
+ final InternalError error = new InternalError(message);
+ throw (InternalError) error.initCause(exception);
+ }
+ }
+
+ /**
+ * <p>Parse the specified {@link String} into a {@link Path} and resolve it
+ * against this one.</p>
+ *
+ * @throws NullPointerException if the path {@link String} was <b>null</b>.
+ */
+ public Path resolve(String path, String encoding)
+ throws UnsupportedEncodingException {
+ if (encoding == null) encoding = DEFAULT_ENCODING;
+ if (path == null) return this;
+ return this.resolve(parse(path, encoding));
+ }
+
+ /* ====================================================================== */
+
+ private static Stack resolve(Stack stack, boolean absolute, List elements) {
+ /* If we have no source stack we create a new empty one */
+ if (stack == null) stack = new Stack();
+ /* A flag indicating whether we are at the "root" path element. */
+ boolean atroot = absolute && stack.empty();
+ /* Iterate through the current path elements to see what to do. */
+ for (Iterator iter = elements.iterator(); iter.hasNext(); ) {
+ final Element element = (Element) iter.next();
+ /* If this is the "." (current) path element, skip it. */
+ if (".".equals(element.getName())) continue;
+ /* If this is the ".." (parent) path element, it gets nasty. */
+ if ("..".equals(element.getName())) {
+ /* The root path's parent is always itself */
+ if (atroot) continue;
+ /* We're not at root and have the stack, relative ".." */
+ if (stack.size() == 0) {
+ stack.push(element);
+ /* We're not at root, but we have stuff in the stack */
+ } else {
+ /* Get the last element in the stack */
+ final Element prev = (Element) stack.peek();
+ /* If the last element is "..", add another one */
+ if ("..".equals(prev.getName())) stack.push(element);
+ /* The last element was not "..", pop it out */
+ else stack.pop();
+ /* If absoulte and stack is empty, we're at root */
+ if (absolute) atroot = stack.size() == 0;
+ }
+ } else {
+ /* Normal element processing follows... */
+ stack.push(element);
+ atroot = false;
+ }
+ }
+ return stack;
+ }
+
+ /* ====================================================================== */
+ /* RELATIVIZATION METHODS */
+ /* ====================================================================== */
+
+ /**
+ * <p>Parse the specified {@link String} into a {@link Path} and relativize
+ * it against this one.</p>
+ */
+ public Path relativize(String path) {
+ try {
+ return this.relativize(parse(path, DEFAULT_ENCODING));
+ } catch (UnsupportedEncodingException exception) {
+ final String message = "Unsupported encoding " + DEFAULT_ENCODING;
+ final InternalError error = new InternalError(message);
+ throw (InternalError) error.initCause(exception);
+ }
+ }
+
+ /**
+ * <p>Parse the specified {@link String} into a {@link Path} and relativize
+ * it against this one.</p>
+ */
+ public Path relativize(String path, String encoding)
+ throws UnsupportedEncodingException {
+ if (encoding == null) encoding = DEFAULT_ENCODING;
+ return this.relativize(parse(path, encoding));
+ }
+
+ /**
+ * <p>Retrieve the relativization path from this {@link Path} to the
+ * specified {@link Path}.</p>
+ */
+ public Path relativize(Path path) {
+ /* No matter what, always return the aggregate of all parameters */
+ final List parameters = new ArrayList();
+ if (this.parameters != null) parameters.addAll(this.parameters);
+ if (path.parameters != null) parameters.addAll(path.parameters);
+ final Parameters params = Parameters.create(parameters, ';');
+
+ /* We are absolute and the specified path is absolute, we process */
+ if ((path.absolute) && (this.absolute)) {
+ /* Find the max number of paths we should examine */
+ final int num = this.collection ? this.size() : this.size() - 1;
+
+ /* Process the two absolute paths to check common elements */
+ int skip = 0;
+ for (int x = 0; (x < num) && (x < path.size()); x ++) {
+ if (path.paths[x].equals(this.paths[x])) skip ++;
+ else break;
+ }
+
+ /* Figure out if the resulting path is a collection */
+ final boolean collection;
+ if (path.size() > skip) collection = path.collection;
+ else if (this.size() > skip) collection = true;
+ else collection = this.collection;
+
+ /* Recreate the path to return by adding ".." and the paths */
+ final List elems = new ArrayList();
+ for (int x = skip; x < num; x ++) elems.add(new Element("..", null));
+ elems.addAll(path.subList(skip, path.size()));
+ return new Path(elems, false, collection);
+ }
+
+ /*
+ * Here we are in one of the following cases:
+ * - the specified path is already relative, so why bother?
+ * - we are relative and the specified path is absolute: in this case
+ * we can't possibly know how far away we are located from the root
+ * so, we only have one option, to return the absolute path.
+ * In all cases, though, before returning the specified path, we just
+ * merge ours and the path's parameters.
+ */
+ if (this.absolute && (! path.absolute)) {
+ /*
+ * Ok, let's bother, we're absolute and the specified is not. This
+ * means that if we resolve the path, we can find another absolute
+ * path, and therefore we can do a better job at relativizin it.
+ */
+ return this.relativize(this.resolve(path));
+ }
+ /* We'll never going to be able to do better than this */
+ return new Path(path, path.absolute, path.collection, params);
+ }
+
+ /* ====================================================================== */
+ /* PUBLIC EXPOSED METHODS */
+ /* ====================================================================== */
+
+ /**
+ * <p>Return the {@link Path.Element Element} instance at
+ * the specified index.</p>
+ */
+ public Object get(int index) {
+ return this.paths[index];
+ }
+
+ /**
+ * <p>Return the number of {@link Path.Element Element}
+ * instances contained by this instance.</p>
+ */
+ public int size() {
+ return this.paths.length;
+ }
+
+ /**
+ * <p>Checks if this {@link Path Path} instance represents
+ * an absolute path.</p>
+ */
+ public boolean isAbsolute() {
+ return this.absolute;
+ }
+
+ /**
+ * <p>Checks if this {@link Path Path} instance represents
+ * a collection.</p>
+ */
+ public boolean isCollection() {
+ return this.collection;
+ }
+
+ /**
+ * <p>Returns the collection of {@link Parameters Parameters}
+ * contained by this instance or <b>null</b>.</p>
+ */
+ public Parameters getParameters() {
+ return this.parameters;
+ }
+
+ /* ====================================================================== */
+ /* OBJECT METHODS */
+ /* ====================================================================== */
+
+ /**
+ * <p>Return the URL-encoded {@link String} representation of this
+ * {@link Path Path} instance.</p>
+ */
+ public String toString() {
+ return this.string;
+ }
+
+ /**
+ * <p>Return the URL-encoded {@link String} representation of this
+ * {@link Path Path} instance using the specified
+ * character encoding.</p>
+ */
+ public String toString(String encoding)
+ throws UnsupportedEncodingException {
+ StringBuffer buffer = new StringBuffer();
+ if (this.absolute) buffer.append('/');
+ final int last = this.paths.length - 1;
+ for (int x = 0; x < last; x ++) {
+ buffer.append(this.paths[x].toString(encoding)).append('/');
+ }
+ if (last >= 0) {
+ buffer.append(this.paths[last].toString(encoding));
+ if (this.collection) buffer.append('/');
+ }
+ if (this.parameters != null)
+ buffer.append(';').append(this.parameters.toString(encoding));
+ return buffer.toString();
+ }
+
+ /**
+ * <p>Return the hash code value of this
+ * {@link Path Path} instance.</p>
+ */
+ public int hashCode() {
+ return this.string.hashCode();
+ }
+
+ /**
+ * <p>Check if the specified {@link Object} is equal to this
+ * {@link Path Path} instance.</p>
+ *
+ * <p>The specified {@link Object} is considered equal to this one if
+ * it is <b>non-null</b>, is a {@link Path Path}
+ * instance and its {@link #toString() string representation} equals
+ * this one's.</p>
+ */
+ public boolean equals(Object object) {
+ if ((object != null) && (object instanceof Path)) {
+ return this.string.equals(((Path) object).string);
+ }
+ return false;
+ }
+
+ /* ====================================================================== */
+ /* PUBLIC INNER CLASSES */
+ /* ====================================================================== */
+
+ /**
+ * <p>The {@link Path.Element Element} class represents a path
+ * element within the {@link Path Path} structure.</p>
+ *
+ * @author <a href="http://could.it/">Pier Fumagalli</a>
+ */
+ public static class Element implements Encodable {
+
+ /** <p>The name of this path element (decoded).</p> */
+ private final String name;
+ /** <p>The extra path information of this path element (decoded).</p> */
+ private final String extra;
+ /** <p>The {@link String} representation of this (encoded).</p> */
+ private final String string;
+
+ /**
+ * <p>Create a new {@link Path.Element Element} instance given its
+ * url-decoded components name and extra.</p>
+ *
+ * @throws NullPointerException if the specified name was <b>null</b>.
+ */
+ public Element(String name, String extra) {
+ if (name == null) throw new NullPointerException("Null path name");
+ this.name = name;
+ this.extra = extra;
+ this.string = EncodingTools.toString(this);
+ }
+
+ /* ================================================================== */
+ /* PUBLIC EXPOSED METHODS */
+ /* ================================================================== */
+
+ /**
+ * <p>Return the url-decoded {@link String} name of this
+ * {@link Path.Element Element}.</p>
+ */
+ public String getName() {
+ return this.name;
+ }
+
+ /**
+ * <p>Return the url-decoded {@link String} extra path of this
+ * {@link Path.Element Element}.</p>
+ */
+ public String getExtra() {
+ return this.extra;
+ }
+
+ /* ================================================================== */
+ /* OBJECT METHODS */
+ /* ================================================================== */
+
+ /**
+ * <p>Return the URL-encoded {@link String} representation of this
+ * {@link Path.Element Element} instance.</p>
+ */
+ public String toString() {
+ return this.string;
+ }
+
+ /**
+ * <p>Return the URL-encoded {@link String} representation of this
+ * {@link Path.Element Element} instance using the specified
+ * character encoding.</p>
+ */
+ public String toString(String encoding)
+ throws UnsupportedEncodingException {
+ final StringBuffer buffer = new StringBuffer();
+ buffer.append(EncodingTools.urlEncode(this.name, encoding));
+ if (this.extra != null) {
+ buffer.append('!');
+ buffer.append(EncodingTools.urlEncode(this.extra, encoding));
+ }
+ return buffer.toString();
+ }
+
+ /**
+ * <p>Return the hash code value of this
+ * {@link Path.Element Element} instance.</p>
+ */
+ public int hashCode() {
+ return this.string.hashCode();
+ }
+
+ /**
+ * <p>Check if the specified {@link Object} is equal to this
+ * {@link Path.Element Element} instance.</p>
+ *
+ * <p>The specified {@link Object} is considered equal to this one if
+ * it is <b>non-null</b>, is a {@link Path.Element Element}
+ * instance and its {@link #toString() string representation} equals
+ * this one's.</p>
+ */
+ public boolean equals(Object object) {
+ if ((object != null) && (object instanceof Element)) {
+ return this.string.equals(((Element) object).string);
+ }
+ return false;
+ }
+ }
+}
\ No newline at end of file
Propchange: maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/util/location/Path.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/util/location/package.html
URL: http://svn.apache.org/viewvc/maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/util/location/package.html?rev=636822&view=auto
==============================================================================
--- maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/util/location/package.html (added)
+++ maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/util/location/package.html Thu Mar 13 11:28:26 2008
@@ -0,0 +1,29 @@
+<html>
+ <head>
+ <title>Location Utilities</title>
+ </head>
+ <body>
+ <p>
+ This package contains a number of utility classes to parse and
+ work with URLs.
+ </p>
+ <p>
+ The {@link java.net.URL} class already provides most of the functionality
+ covered by this package, but certain limitations in its implementation
+ (for example, all schemes <i>must</i> be registered with the
+ {java.net.URLStreamHandler} class before they can be used), prompted
+ the re-development of a similar API.
+ </p>
+ <p>
+ For further details on what the different classes in this package mean
+ and how they interact, see the {@link it.could.util.location.Location}
+ class documentation, but as a reference, this is a picture outlining
+ the structure:
+ </p>
+ <div align="center">
+ <a href="url.pdf" target="_new" title="PDF Version">
+ <img src="url.gif" alt="URL components" border="0">
+ </a>
+ </div>
+ </body>
+</html>
\ No newline at end of file
Propchange: maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/util/location/package.html
------------------------------------------------------------------------------
svn:eol-style = native
Added: maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/util/location/url.gif
URL: http://svn.apache.org/viewvc/maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/util/location/url.gif?rev=636822&view=auto
==============================================================================
Binary file - no diff available.
Propchange: maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/util/location/url.gif
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/util/location/url.pdf
URL: http://svn.apache.org/viewvc/maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/util/location/url.pdf?rev=636822&view=auto
==============================================================================
Binary file - no diff available.
Propchange: maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/util/location/url.pdf
------------------------------------------------------------------------------
svn:mime-type = application/pdf
Added: maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/util/package.html
URL: http://svn.apache.org/viewvc/maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/util/package.html?rev=636822&view=auto
==============================================================================
--- maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/util/package.html (added)
+++ maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/util/package.html Thu Mar 13 11:28:26 2008
@@ -0,0 +1,11 @@
+<html>
+ <head>
+ <title>Encoding Utilities</title>
+ </head>
+ <body>
+ <p>
+ This package contains a number of utility classes which can come handy
+ from time to time when writing Java code.
+ </p>
+ </body>
+</html>
\ No newline at end of file
Propchange: maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/util/package.html
------------------------------------------------------------------------------
svn:eol-style = native
Added: maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVException.java
URL: http://svn.apache.org/viewvc/maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVException.java?rev=636822&view=auto
==============================================================================
--- maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVException.java (added)
+++ maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVException.java Thu Mar 13 11:28:26 2008
@@ -0,0 +1,132 @@
+/* ========================================================================== *
+ * Copyright (C) 2004-2006, Pier Fumagalli <http://could.it/> *
+ * All rights reserved. *
+ * ========================================================================== *
+ * *
+ * Licensed under the Apache License, Version 2.0 (the "License"). You may *
+ * not use this file except in compliance with the License. You may obtain a *
+ * copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>. *
+ * *
+ * Unless required by applicable law or agreed to in writing, software *
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT *
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the *
+ * License for the specific language governing permissions and limitations *
+ * under the License. *
+ * *
+ * ========================================================================== */
+package it.could.webdav;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+
+/**
+ * <p>A {@link RuntimeException} representing a
+ * <a href="http://www.rfc-editor.org/rfc/rfc2518.txt">WebDAV</a>
+ * response for a specified {@link DAVResource}.</p>
+ *
+ * @author <a href="http://could.it/">Pier Fumagalli</a>
+ */
+public class DAVException extends RuntimeException {
+
+ private DAVResource resource = null;
+ private int status = 0;
+
+ /**
+ * <p>Create a new {@link DAVException} instance.</p>
+ */
+ public DAVException(int status, String message) {
+ this(status, message, null, null);
+ }
+
+ /**
+ * <p>Create a new {@link DAVException} instance.</p>
+ */
+ public DAVException(int status, String message, Throwable throwable) {
+ this(status, message, throwable, null);
+ }
+
+ /**
+ * <p>Create a new {@link DAVException} instance.</p>
+ */
+ public DAVException(int status, String message, DAVResource resource) {
+ this(status, message, null, resource);
+ }
+
+ /**
+ * <p>Create a new {@link DAVException} instance.</p>
+ */
+ public DAVException(int s, String m, Throwable t, DAVResource r) {
+ super(m, t);
+ this.resource = r;
+ this.status = s;
+ }
+
+ /**
+ * <p>Return the status code associated with this instance.</p>
+ */
+ public int getStatus() {
+ return this.status;
+ }
+
+ /**
+ * <p>Return the {@link DAVResource} associated with this instance.</p>
+ */
+ public DAVResource getResource() {
+ return this.resource;
+ }
+
+ /**
+ * <p>Write the body of this {@link DAVException} to the specified
+ * {@link DAVTransaction}'s output.</p>
+ */
+ public void write(DAVTransaction transaction)
+ throws IOException {
+ transaction.setContentType("text/html; charset=\"UTF-8\"");
+ transaction.setStatus(this.getStatus());
+
+ /* Prepare and log the error message */
+ String message = DAVUtilities.getStatusMessage(this.getStatus());
+ if (message == null) {
+ transaction.setStatus(500);
+ message = Integer.toString(this.getStatus()) + " Unknown";
+ }
+
+ /* Write the error message to the client */
+ PrintWriter out = transaction.write("UTF-8");
+ out.println("<html>");
+ out.print("<head><title>Error ");
+ out.print(message);
+ out.println("</title></head>");
+ out.println("<body>");
+ out.print("<p><b>Error ");
+ out.print(message);
+ out.println("</b></p>");
+
+ /* Check if we have a resource associated with the extension */
+ if (this.getResource() != null) {
+ String r = transaction.lookup(this.getResource()).toASCIIString();
+ out.print("<p>Resource in error: <a href=\"");
+ out.print(r);
+ out.println("\">");
+ out.print(r);
+ out.println("</a></p>");
+ }
+
+ /* Process any exception and its cause */
+ Throwable throwable = this;
+ out.println("<hr /><p>Exception details:</p>");
+ while (throwable != null) {
+ out.print("<pre>");
+ throwable.printStackTrace(out);
+ out.println("</pre>");
+ throwable = throwable.getCause();
+ if (throwable != null) out.println("<hr /><p>Caused by:</p>");
+ }
+
+ /* Close up the HTML */
+ out.println("</body>");
+ out.println("</html>");
+ out.flush();
+ }
+}
Propchange: maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVException.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVInputStream.java
URL: http://svn.apache.org/viewvc/maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVInputStream.java?rev=636822&view=auto
==============================================================================
--- maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVInputStream.java (added)
+++ maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVInputStream.java Thu Mar 13 11:28:26 2008
@@ -0,0 +1,165 @@
+/* ========================================================================== *
+ * Copyright (C) 2004-2006, Pier Fumagalli <http://could.it/> *
+ * All rights reserved. *
+ * ========================================================================== *
+ * *
+ * Licensed under the Apache License, Version 2.0 (the "License"). You may *
+ * not use this file except in compliance with the License. You may obtain a *
+ * copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>. *
+ * *
+ * Unless required by applicable law or agreed to in writing, software *
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT *
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the *
+ * License for the specific language governing permissions and limitations *
+ * under the License. *
+ * *
+ * ========================================================================== */
+package it.could.webdav;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+
+/**
+ * <p>A specialized {@link InputStream} to read from {@link DAVResource}s.</p>
+ *
+ * <p>This specialized {@link InputStream} never throws {@link IOException}s,
+ * but rather relies on the unchecked {@link DAVException} to notify the
+ * framework of the correct DAV errors.</p>
+ *
+ * @author <a href="http://could.it/">Pier Fumagalli</a>
+ */
+public class DAVInputStream extends InputStream {
+
+ /** <p>The {@link InputStream} of the source {@link File}. </p> */
+ protected InputStream input = null;
+ /** <p>The {@link DAVResource} associated with this instance. </p> */
+ private DAVResource resource = null;
+
+ /**
+ * <p>Create a new {@link DAVInputStream} instance.</p>
+ */
+ protected DAVInputStream(DAVResource resource) {
+ if (resource == null) throw new NullPointerException();
+ init(resource);
+ }
+
+ protected void init(DAVResource resource)
+ {
+ try {
+ this.input = new FileInputStream(resource.getFile());
+ } catch (IOException e) {
+ String message = "Unable to read from resource";
+ throw new DAVException (403, message, e, resource);
+ }
+ }
+
+ /**
+ * <p>Read data from this {@link InputStream}.</p>
+ */
+ public int read() {
+ if (this.input == null) throw new IllegalStateException("Closed");
+ try {
+ return input.read();
+ } catch (IOException e) {
+ throw new DAVException(403, "Can't read data", e, this.resource);
+ }
+ }
+
+ /**
+ * <p>Read data from this {@link InputStream}.</p>
+ */
+ public int read(byte b[]) {
+ if (this.input == null) throw new IllegalStateException("Closed");
+ try {
+ return input.read(b);
+ } catch (IOException e) {
+ throw new DAVException(403, "Can't read data", e, this.resource);
+ }
+ }
+
+ /**
+ * <p>Read data from this {@link InputStream}.</p>
+ */
+ public int read(byte b[], int off, int len) {
+ if (this.input == null) throw new IllegalStateException("Closed");
+ try {
+ return input.read(b, off, len);
+ } catch (IOException e) {
+ throw new DAVException(403, "Can't read data", e, this.resource);
+ }
+ }
+
+ /**
+ * <p>Skip a specified amount of data reading from this
+ * {@link InputStream}.</p>
+ */
+ public long skip(long n) {
+ if (this.input == null) throw new IllegalStateException("Closed");
+ try {
+ return input.skip(n);
+ } catch (IOException e) {
+ throw new DAVException(403, "Can't skip over", e, this.resource);
+ }
+ }
+
+ /**
+ * <p>Return the number of bytes that can be read or skipped from this
+ * {@link InputStream} without blocking.</p>
+ */
+ public int available() {
+ if (this.input == null) throw new IllegalStateException("Closed");
+ try {
+ return input.available();
+ } catch (IOException e) {
+ throw new DAVException(403, "Can't skip over", e, this.resource);
+ }
+ }
+
+ /**
+ * <p>Return the number of bytes that can be read or skipped from this
+ * {@link InputStream} without blocking.</p>
+ */
+ public void close() {
+ if (this.input == null) return;
+ try {
+ this.input.close();
+ } catch (IOException e) {
+ throw new DAVException(403, "Can't close", e, this.resource);
+ } finally {
+ this.input = null;
+ }
+ }
+
+ /**
+ * <p>Marks the current position in this {@link InputStream}.</p>
+ */
+ public void mark(int readlimit) {
+ if (this.input == null) throw new IllegalStateException("Closed");
+ this.input.mark(readlimit);
+ }
+
+ /**
+ * <p>Repositions this stream to the position at the time the
+ * {@link #mark(int)} method was last called on this
+ * {@link InputStream}.</p>
+ */
+ public void reset() {
+ if (this.input == null) throw new IllegalStateException("Closed");
+ try {
+ input.reset();
+ } catch (IOException e) {
+ throw new DAVException(403, "Can't reset", e, this.resource);
+ }
+ }
+
+ /**
+ * <p>Tests if this {@link InputStream} supports the {@link #mark(int)}
+ * and {@link #reset()} methods.</p>
+ */
+ public boolean markSupported() {
+ if (this.input == null) throw new IllegalStateException("Closed");
+ return this.input.markSupported();
+ }
+}
Propchange: maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVInputStream.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVListener.java
URL: http://svn.apache.org/viewvc/maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVListener.java?rev=636822&view=auto
==============================================================================
--- maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVListener.java (added)
+++ maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVListener.java Thu Mar 13 11:28:26 2008
@@ -0,0 +1,46 @@
+/* ========================================================================== *
+ * Copyright (C) 2004-2006, Pier Fumagalli <http://could.it/> *
+ * All rights reserved. *
+ * ========================================================================== *
+ * *
+ * Licensed under the Apache License, Version 2.0 (the "License"). You may *
+ * not use this file except in compliance with the License. You may obtain a *
+ * copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>. *
+ * *
+ * Unless required by applicable law or agreed to in writing, software *
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT *
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the *
+ * License for the specific language governing permissions and limitations *
+ * under the License. *
+ * *
+ * ========================================================================== */
+package it.could.webdav;
+
+/**
+ * <p>A simple interface identifying a {@link DAVRepository} event listener.</p>
+ *
+ * @author <a href="http://could.it/">Pier Fumagalli</a>
+ */
+public interface DAVListener {
+
+ /** <p>An event representing the creation of a collection.</p> */
+ public static final int COLLECTION_CREATED = 1;
+ /** <p>An event representing the deletion of a collection.</p> */
+ public static final int COLLECTION_REMOVED = 2;
+ /** <p>An event representing the creation of a resource.</p> */
+ public static final int RESOURCE_CREATED = 3;
+ /** <p>An event representing the deletion of a resource.</p> */
+ public static final int RESOURCE_REMOVED = 4;
+ /** <p>An event representing the modification of a resource.</p> */
+ public static final int RESOURCE_MODIFIED = 5;
+
+ /**
+ * <p>Notify this {@link DAVListener} of an action occurred on a
+ * specified {@link DAVResource}.</p>
+ *
+ * @param resource the {@link DAVResource} associated with the notification.
+ * @param event a number identifying the type of the notification.
+ */
+ public void notify(DAVResource resource, int event);
+
+}
Propchange: maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVListener.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVLogger.java
URL: http://svn.apache.org/viewvc/maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVLogger.java?rev=636822&view=auto
==============================================================================
--- maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVLogger.java (added)
+++ maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVLogger.java Thu Mar 13 11:28:26 2008
@@ -0,0 +1,86 @@
+/* ========================================================================== *
+ * Copyright (C) 2004-2006, Pier Fumagalli <http://could.it/> *
+ * All rights reserved. *
+ * ========================================================================== *
+ * *
+ * Licensed under the Apache License, Version 2.0 (the "License"). You may *
+ * not use this file except in compliance with the License. You may obtain a *
+ * copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>. *
+ * *
+ * Unless required by applicable law or agreed to in writing, software *
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT *
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the *
+ * License for the specific language governing permissions and limitations *
+ * under the License. *
+ * *
+ * ========================================================================== */
+package it.could.webdav;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+
+/**
+ * <p>A simplicisting class defining an esay way to log stuff to the
+ * {@link ServletContext}.</p>
+ *
+ * @author <a href="http://could.it/">Pier Fumagalli</a>
+ */
+public class DAVLogger {
+
+ private final ServletContext context;
+ private final String servletName;
+ private final boolean debug;
+
+ /**
+ * <p>Create a new {@link DAVLogger} from a {@link ServletConfig}.</p>
+ */
+ public DAVLogger(ServletConfig config, boolean debug) {
+ this.context = config.getServletContext();
+ this.servletName = config.getServletName();
+ this.debug = debug;
+ }
+
+ /**
+ * <p>Log a debug message to the context logger.</p>
+ */
+ public void debug(String message) {
+ if (this.debug) this.doLog(message, null);
+ }
+
+ /**
+ * <p>Log a debug message and related exception to the context logger.</p>
+ */
+ public void debug(String message, Throwable throwable) {
+ if (this.debug) this.doLog(message, throwable);
+ }
+
+ /**
+ * <p>Log a message to the context logger.</p>
+ */
+ public void log(String message) {
+ this.doLog(message, null);
+ }
+
+ /**
+ * <p>Log a message and related exception to the context logger.</p>
+ */
+ public void log(String message, Throwable throwable) {
+ this.doLog(message, throwable);
+ }
+
+ /**
+ * <p>Internal method for formatting messages and logging.</p>
+ */
+ private void doLog(String message, Throwable throwable) {
+ if ((message == null) && (throwable == null)) return;
+ if ((message == null) || ("".equals(message))) message = "No message";
+
+ StringBuffer buffer = new StringBuffer();
+ buffer.append('[');
+ buffer.append(this.servletName);
+ buffer.append("] ");
+ buffer.append(message);
+ if (throwable == null) this.context.log(buffer.toString());
+ else this.context.log(buffer.toString(), throwable);
+ }
+}
Propchange: maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVLogger.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVMethod.java
URL: http://svn.apache.org/viewvc/maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVMethod.java?rev=636822&view=auto
==============================================================================
--- maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVMethod.java (added)
+++ maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVMethod.java Thu Mar 13 11:28:26 2008
@@ -0,0 +1,41 @@
+/* ========================================================================== *
+ * Copyright (C) 2004-2006, Pier Fumagalli <http://could.it/> *
+ * All rights reserved. *
+ * ========================================================================== *
+ * *
+ * Licensed under the Apache License, Version 2.0 (the "License"). You may *
+ * not use this file except in compliance with the License. You may obtain a *
+ * copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>. *
+ * *
+ * Unless required by applicable law or agreed to in writing, software *
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT *
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the *
+ * License for the specific language governing permissions and limitations *
+ * under the License. *
+ * *
+ * ========================================================================== */
+package it.could.webdav;
+
+import java.io.IOException;
+
+
+/**
+ * <p>An interface describing the implementation of a
+ * <a href="http://www.rfc-editor.org/rfc/rfc2518.txt">WebDAV</a>
+ * method.</p>
+ *
+ * @author <a href="http://could.it/">Pier Fumagalli</a>
+ */
+public interface DAVMethod {
+
+ /**
+ * <p>Process the specified {@link DAVTransaction}.</p>
+ *
+ * @param transaction An object encapsulaing a WebDAV request/response.
+ * @param resource The {@link DAVResource} to process.
+ * @throws IOException If an I/O error occurred.
+ */
+ public void process(DAVTransaction transaction, DAVResource resource)
+ throws IOException;
+
+}
Propchange: maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVMethod.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVMultiStatus.java
URL: http://svn.apache.org/viewvc/maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVMultiStatus.java?rev=636822&view=auto
==============================================================================
--- maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVMultiStatus.java (added)
+++ maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVMultiStatus.java Thu Mar 13 11:28:26 2008
@@ -0,0 +1,149 @@
+/* ========================================================================== *
+ * Copyright (C) 2004-2006, Pier Fumagalli <http://could.it/> *
+ * All rights reserved. *
+ * ========================================================================== *
+ * *
+ * Licensed under the Apache License, Version 2.0 (the "License"). You may *
+ * not use this file except in compliance with the License. You may obtain a *
+ * copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>. *
+ * *
+ * Unless required by applicable law or agreed to in writing, software *
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT *
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the *
+ * License for the specific language governing permissions and limitations *
+ * under the License. *
+ * *
+ * ========================================================================== */
+package it.could.webdav;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+
+/**
+ * <p>A {@link DAVException} representing a
+ * <a href="http://www.rfc-editor.org/rfc/rfc2518.txt">WebDAV</a>
+ * <code>207</code> (Multi-Status) response.</p>
+ *
+ * @author <a href="http://could.it/">Pier Fumagalli</a>
+ */
+public class DAVMultiStatus extends DAVException {
+
+ private Set responses = new HashSet();
+
+ /**
+ * <p>Create a new {@link DAVMultiStatus} instance.</p>
+ */
+ public DAVMultiStatus() {
+ super(207, "Multi-Status response");
+ }
+
+ /**
+ * <p>Write the body of the multi-status response to the specified
+ * {@link DAVTransaction}'s output.</p>
+ */
+ public void write(DAVTransaction transaction)
+ throws IOException {
+ /* What to do on a collection resource */
+ transaction.setStatus(207);
+ transaction.setContentType("text/xml; charset=\"UTF-8\"");
+ PrintWriter out = transaction.write("UTF-8");
+
+ /* Output the XML declaration and the root document tag */
+ out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+ out.println("<D:multistatus xmlns:D=\"DAV:\">");
+
+ Iterator responses = this.responses.iterator();
+ while (responses.hasNext()) {
+ Response response = (Response) responses.next();
+ out.println(" <D:response>");
+ out.print(" <D:href>");
+ out.print(transaction.lookup(response.resource));
+ out.println("</D:href>");
+
+ if (response.status != 0) {
+ out.print(" <D:status>HTTP/1.1 ");
+ out.print(DAVUtilities.getStatusMessage(response.status));
+ out.println("</D:status>");
+ }
+
+ if (response.message != null) {
+ out.print(" <D:responsedescription>");
+ out.print(response.message);
+ out.println("</D:responsedescription>");
+ }
+
+ out.println(" </D:response>");
+ }
+
+ out.println("</D:multistatus>");
+ out.flush();
+ }
+
+ /**
+ * <p>Return the number of responses held in this instance.</p>
+ */
+ public int size() {
+ return this.responses.size();
+ }
+
+ /**
+ * <p>Merge the responses held into the specified {@link DAVMultiStatus}
+ * into this instance.</p>
+ */
+ public void merge(DAVMultiStatus multistatus) {
+ if (multistatus == null) return;
+ Iterator iterator = multistatus.responses.iterator();
+ while (iterator.hasNext()) this.responses.add(iterator.next());
+ }
+
+ /**
+ * <p>Merge the details held into the specified {@link DAVException}
+ * into this instance.</p>
+ */
+ public void merge(DAVException exception) {
+ DAVResource resource = exception.getResource();
+ if (resource == null) throw exception;
+
+ int status = exception.getStatus();
+ String message = exception.getMessage();
+ this.responses.add(new Response(resource, status, message));
+ }
+
+ private static class Response implements Comparable {
+ private DAVResource resource = null;
+ private int status = 0;
+ private String message = null;
+
+ public Response(Response response) {
+ this(response.resource, response.status, response.message);
+ }
+
+ public Response(DAVResource resource, int status, String message) {
+ if (resource == null) throw new NullPointerException();
+ this.resource = resource;
+ this.status = status;
+ this.message = message;
+ }
+
+ public int hashCode() {
+ return this.resource.hashCode();
+ }
+
+ public int compareTo(Object object) {
+ Response response = (Response) object;
+ return (this.resource.compareTo(response.resource));
+ }
+
+ public boolean equals(Object object) {
+ if (object instanceof Response) {
+ Response response = (Response) object;
+ return (this.resource.equals(response.resource));
+ }
+ return false;
+ }
+ }
+}
Propchange: maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVMultiStatus.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVNotModified.java
URL: http://svn.apache.org/viewvc/maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVNotModified.java?rev=636822&view=auto
==============================================================================
--- maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVNotModified.java (added)
+++ maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVNotModified.java Thu Mar 13 11:28:26 2008
@@ -0,0 +1,56 @@
+/* ========================================================================== *
+ * Copyright (C) 2004-2006, Pier Fumagalli <http://could.it/> *
+ * All rights reserved. *
+ * ========================================================================== *
+ * *
+ * Licensed under the Apache License, Version 2.0 (the "License"). You may *
+ * not use this file except in compliance with the License. You may obtain a *
+ * copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>. *
+ * *
+ * Unless required by applicable law or agreed to in writing, software *
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT *
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the *
+ * License for the specific language governing permissions and limitations *
+ * under the License. *
+ * *
+ * ========================================================================== */
+package it.could.webdav;
+
+import java.io.IOException;
+
+/**
+ * <p>A simple {@link DAVException} encapsulating an
+ * <a href="http://www.rfc-editor.org/rfc/rfc2616.txt">HTTP</a> not modified
+ * response.</p>
+ *
+ * @author <a href="http://could.it/">Pier Fumagalli</a>
+ */
+public class DAVNotModified extends DAVException {
+
+ private DAVResource resource = null;
+
+ /**
+ * <p>Create a new {@link DAVNotModified} instance.</p>
+ */
+ public DAVNotModified(DAVResource resource) {
+ super(304, "Resource Not Modified");
+ this.resource = resource;
+ }
+
+ /**
+ * <p>Write the body of this {@link DAVNotModified} to the specified
+ * {@link DAVTransaction}'s output.</p>
+ */
+ public void write(DAVTransaction transaction)
+ throws IOException {
+ transaction.setStatus(this.getStatus());
+
+ /* Figure out what we're dealing with here */
+ String etag = resource.getEntityTag();
+ String lmod = DAVUtilities.formatHttpDate(resource.getLastModified());
+
+ /* Set the normal headers that are required for a GET */
+ if (etag != null) transaction.setHeader("ETag", etag);
+ if (lmod != null) transaction.setHeader("Last-Modified", lmod);
+ }
+}
Propchange: maven/archiva/branches/springy/archiva-web/archiva-webdav/src/main/java/it/could/webdav/DAVNotModified.java
------------------------------------------------------------------------------
svn:eol-style = native