You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by mr...@apache.org on 2005/11/27 08:10:27 UTC
svn commit: r349187 [4/6] - in /struts/flow/trunk: ./ src/examples/WEB-INF/
src/examples/WEB-INF/guess/ src/examples/WEB-INF/portlet/
src/examples/WEB-INF/remote/ src/examples/remote/ src/java/
src/java/org/apache/struts/flow/ src/java/org/apache/strut...
Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/PageLocalScopeHolder.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/PageLocalScopeHolder.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/PageLocalScopeHolder.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/PageLocalScopeHolder.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,89 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * 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 org.apache.struts.flow.core.javascript.fom;
+
+import org.mozilla.javascript.Scriptable;
+import org.mozilla.javascript.ScriptableObject;
+
+/**
+ * @version CVS $Id: PageLocalScopeHolder.java 36239 2004-08-11 18:28:06Z vgritsenko $
+ */
+public class PageLocalScopeHolder implements PageLocalScope {
+
+ private Scriptable scope;
+ private PageLocalScopeImpl delegate;
+
+ public PageLocalScopeHolder(Scriptable scope) {
+ this.scope = scope;
+ }
+
+ public boolean has(PageLocal local, String name) {
+ return delegate.has(local, name);
+ }
+
+ public boolean has(PageLocal local, int index) {
+ return delegate.has(local, index);
+ }
+
+ public Object get(PageLocal local, String name) {
+ return delegate.get(local, name);
+ }
+
+ public Object get(PageLocal local, int index) {
+ return delegate.get(local, index);
+ }
+
+ public void put(PageLocal local, String name, Object value) {
+ delegate.put(local, name, value);
+ }
+
+ public void put(PageLocal local, int index, Object value) {
+ delegate.put(local, index, value);
+ }
+
+ public void delete(PageLocal local, String name) {
+ delegate.delete(local, name);
+ }
+
+ public void delete(PageLocal local, int index) {
+ delegate.delete(local, index);
+ }
+
+ public Object[] getIds(PageLocal local) {
+ return delegate.getIds(local);
+ }
+
+ public Object getDefaultValue(PageLocal local, Class hint) {
+ return delegate.getDefaultValue(local, hint);
+ }
+
+ public void setDelegate(PageLocalScopeImpl delegate) {
+ this.delegate = delegate;
+ }
+
+ public PageLocalScopeImpl getDelegate() {
+ return delegate;
+ }
+
+ public PageLocal createPageLocal() {
+ PageLocalImpl pageLocal = new PageLocalImpl();
+ pageLocal.setPrototype(ScriptableObject.getClassPrototype(scope,
+ pageLocal.getClassName()));
+ pageLocal.setParentScope(scope);
+ pageLocal.setPageLocalScope(this);
+ return pageLocal;
+ }
+}
Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/PageLocalScopeHolder.java
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/PageLocalScopeImpl.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/PageLocalScopeImpl.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/PageLocalScopeImpl.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/PageLocalScopeImpl.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,136 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ *
+ * 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 org.apache.struts.flow.core.javascript.fom;
+
+import org.mozilla.javascript.Context;
+import org.mozilla.javascript.Scriptable;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * @version CVS $Id: PageLocalScopeImpl.java 36239 2004-08-11 18:28:06Z vgritsenko $
+ */
+public class PageLocalScopeImpl implements PageLocalScope {
+
+ private Map locals;
+ private Scriptable scope;
+
+ public PageLocalScopeImpl(Scriptable scope) {
+ locals = new HashMap();
+ this.scope = scope;
+ }
+
+ private Scriptable newObject() {
+ try {
+ return Context.getCurrentContext().newObject(scope);
+ } catch (Exception ignored) {
+ // can't happen here
+ ignored.printStackTrace();
+ throw new Error("error: " + ignored);
+ }
+ }
+
+ private PageLocalScopeImpl(PageLocalScopeImpl toBeCloned) {
+ this.scope = toBeCloned.scope;
+ locals = new HashMap();
+ Iterator iter = toBeCloned.locals.entrySet().iterator();
+ while (iter.hasNext()) {
+ Map.Entry e = (Map.Entry)iter.next();
+ Object key = e.getKey();
+ Object value = e.getValue();
+ // clone it
+ Scriptable obj = (Scriptable)value;
+ Scriptable newObj = newObject();
+ Object[] ids = obj.getIds();
+ for (int i = 0; i < ids.length; i++) {
+ String name = ids[i].toString();
+ newObj.put(name, newObj, obj.get(name, obj));
+ }
+ value = newObj;
+ locals.put(key, value);
+ }
+ }
+
+ private Scriptable resolve(PageLocal local) {
+ final Object id = local.getId();
+ Scriptable result = (Scriptable)locals.get(id);
+ if (result == null) {
+ locals.put(id, result = newObject());
+ }
+ return result;
+ }
+
+ public boolean has(PageLocal local, String name) {
+ Scriptable obj = resolve(local);
+ return obj.has(name, obj);
+ }
+
+ public boolean has(PageLocal local, int index) {
+ Scriptable obj = resolve(local);
+ return obj.has(index, obj);
+ }
+
+ public Object get(PageLocal local, String name) {
+ Scriptable obj = resolve(local);
+ return obj.get(name, obj);
+ }
+
+ public Object get(PageLocal local, int index) {
+ Scriptable obj = resolve(local);
+ return obj.get(index, obj);
+ }
+
+ public void put(PageLocal local, String name, Object value) {
+ Scriptable obj = resolve(local);
+ obj.put(name, obj, value);
+ }
+
+ public void put(PageLocal local, int index, Object value) {
+ Scriptable obj = resolve(local);
+ obj.put(index, obj, value);
+ }
+
+ public void delete(PageLocal local, String name) {
+ Scriptable obj = resolve(local);
+ obj.delete(name);
+ }
+
+ public void delete(PageLocal local, int index) {
+ Scriptable obj = resolve(local);
+ obj.delete(index);
+ }
+
+ public Object[] getIds(PageLocal local) {
+ Scriptable obj = resolve(local);
+ return obj.getIds();
+ }
+
+ public Object getDefaultValue(PageLocal local, Class hint) {
+ Scriptable obj = resolve(local);
+ return obj.getDefaultValue(hint);
+ }
+
+ public PageLocalScopeImpl duplicate() {
+ return new PageLocalScopeImpl(this);
+ }
+
+ public PageLocal createPageLocal() {
+ // not used
+ return null;
+ }
+}
Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/PageLocalScopeImpl.java
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/fom_system.js
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/fom_system.js?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/fom_system.js (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/fom_system.js Sat Nov 26 23:10:08 2005
@@ -0,0 +1,56 @@
+/*
+* Copyright 1999-2004 The Apache Software Foundation
+*
+* 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.
+*/
+FOM_Flow.suicide = new Continuation();
+
+FOM_Flow.prototype.forwardAndWait = function(uri, bizData, fun, ttl) {
+ this.forward(uri, bizData,
+ new FOM_WebContinuation(new Continuation(),
+ this.continuation, ttl));
+ if (fun) {
+ if (!(fun instanceof Function)) {
+ throw "Expected a function instead of: " + fun;
+ }
+ fun();
+ }
+ FOM_Flow.suicide();
+}
+
+FOM_Flow.prototype.handleContinuation = function(k, wk) {
+ k(wk);
+}
+
+FOM_Flow.prototype.createWebContinuation = function(ttl) {
+ var wk = this.makeWebContinuation(new Continuation(), ttl);
+ wk.setBookmark(true);
+ return wk;
+}
+
+/**
+ * Exit the current flowscript invocation.
+ * <p>
+ * There are some flowscript use cases where we want to stop the current
+ * flowscript without creating a continuation, as we don't want the user
+ * to go back to the script.
+ * <p>
+ * An example is a "login" function where the caller function expects this
+ * function to exit only if login is successful, but that has to handle
+ * e.g. a registration process that includes a "cancel" button.
+ */
+FOM_Flow.prototype.exit = function() {
+ FOM_Flow.suicide();
+}
+
+
Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/javascript/fom/fom_system.js
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/location/Locatable.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/location/Locatable.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/location/Locatable.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/location/Locatable.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * 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 org.apache.struts.flow.core.location;
+
+/**
+ * A interface that should be implemented by objects knowning their location (i.e. where they
+ * have been created from).
+ *
+ * @since 2.1.8
+ * @version $Id: Locatable.java 233343 2005-08-18 18:06:44Z sylvain $
+ */
+public interface Locatable {
+ /**
+ * Get the location of this object
+ *
+ * @return the location
+ */
+ Location getLocation();
+}
Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/location/Locatable.java
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/location/LocatableException.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/location/LocatableException.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/location/LocatableException.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/location/LocatableException.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * 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 org.apache.struts.flow.core.location;
+
+/**
+ * Extension of {@link Locatable} for exceptions.
+ * <p>
+ * In order to dump location information in the stacktrace, the <code>getMessage()</code> method of
+ * a {@link Locatable} exception should return a concatenation of the raw message (given in the
+ * constructor) and the exception's location, e.g. "<code>foo failed (file.xml:12:3)</code>". However,
+ * {@link Locatable}-aware classes will want to handle the raw message (i.e. "<code>foo failed</code>")
+ * and location separately. This interface gives access to the raw message.
+ * <p>
+ * <strong>Note:</strong> care should be taken for locatable exceptions to use only immutable and
+ * serializable implementations of {@link Location} ({@see org.apache.struts.flow.core.location.LocationImpl#get(Location)}).
+ *
+ * @since 2.1.8
+ * @version $Id: LocatableException.java 233343 2005-08-18 18:06:44Z sylvain $
+ */
+public interface LocatableException extends Locatable {
+
+ /**
+ * Get the raw message of the exception (the one used in the constructor)
+ *
+ * @return the raw message
+ */
+ public String getRawMessage();
+}
Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/location/LocatableException.java
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/location/LocatedException.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/location/LocatedException.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/location/LocatedException.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/location/LocatedException.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * 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 org.apache.struts.flow.core.location;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.apache.commons.lang.exception.NestableException;
+
+/**
+ * A cascading and located <code>Exception</code>. It is also {@link MultiLocatable} to easily build
+ * stack traces.
+ *
+ * @since 2.1.8
+ * @version $Id: LocatedException.java 291771 2005-09-26 22:32:55Z vgritsenko $
+ */
+public class LocatedException extends NestableException
+ implements LocatableException, MultiLocatable {
+
+ private List locations;
+
+ public LocatedException(String message) {
+ this(message, null, null);
+ }
+
+ public LocatedException(String message, Throwable cause) {
+ this(message, cause, null);
+ }
+
+ public LocatedException(String message, Location location) {
+ this(message, null, location);
+ }
+
+ public LocatedException(String message, Throwable cause, Location location) {
+ super(message, cause);
+ ensureCauseChainIsSet(cause);
+ addCauseLocations(this, cause);
+ addLocation(location);
+ }
+
+ /**
+ * Crawl the cause chain and ensure causes are properly set using {@ link Throwable#initCause}.
+ * This is needed because some exceptions (e.g. SAXException) don't have a {@ link Throwable#getCause}
+ * that is used to print stacktraces.
+ */
+ public static void ensureCauseChainIsSet(Throwable thr) {
+ // Loop either until null or encountering exceptions that use this method.
+ while (thr != null && !(thr instanceof LocatedRuntimeException) && !(thr instanceof LocatedException)) {
+ Throwable parent = ExceptionUtils.getCause(thr);
+ if (thr.getCause() == null && parent != null) {
+ thr.initCause(parent);
+ }
+ thr = parent;
+ }
+ }
+
+ /**
+ * Add to the location stack all locations of an exception chain. This allows to have all possible
+ * location information in the stacktrace, as some exceptions like SAXParseException don't output
+ * their location in printStackTrace().
+ * <p>
+ * Traversal of the call chain stops at the first <code>Locatable</code> exception which is supposed
+ * to handle the loction of its causes by itself.
+ * <p>
+ * This method is static as a convenience for {@link LocatedRuntimeException other implementations}
+ * of locatable exceptions.
+ *
+ * @param self the current locatable exception
+ * @param cause a cause of <code>self</code>
+ */
+ public static void addCauseLocations(MultiLocatable self, Throwable cause) {
+ if (cause == null || cause instanceof Locatable) {
+ // Locatable handles its location itself
+ return;
+ }
+ // Add parent location first
+ addCauseLocations(self, ExceptionUtils.getCause(cause));
+ // then ourselve's
+ Location loc = LocationUtils.getLocation(cause);
+ if (LocationUtils.isKnown(loc)) {
+ // Get the exception's short name
+ String name = cause.getClass().getName();
+ int pos = name.lastIndexOf('.');
+ if (pos != -1) {
+ name = name.substring(pos+1);
+ }
+ loc = new LocationImpl("[" + name + "]", loc.getURI(), loc.getLineNumber(), loc.getColumnNumber());
+ self.addLocation(loc);
+ }
+ }
+
+ public Location getLocation() {
+ return locations == null ? null : (Location)locations.get(0);
+ }
+
+ public List getLocations() {
+ return locations == null ? Collections.EMPTY_LIST : locations;
+ }
+
+ public String getRawMessage() {
+ return super.getMessage();
+ }
+
+ /**
+ * Standard way of building the message of a {@link LocatableException}, as a Java-like
+ * stack trace of locations.
+ *
+ * @param message the exception's message, given by <code>super.getMessage()</code> (can be null)
+ * @param locations the location list (can be null)
+ *
+ * @return the message, or <code>null</code> no message and locations were given.
+ */
+ public static String getMessage(String message, List locations) {
+ if (locations == null || locations.isEmpty()) {
+ return message;
+ }
+
+ // Produce a Java-like stacktrace with locations
+ StringBuffer buf = message == null ? new StringBuffer() : new StringBuffer(message);
+ for (int i = 0; i < locations.size(); i++) {
+ buf.append("\n\tat ").append(LocationUtils.toString((Location)locations.get(i)));
+ }
+ return buf.toString();
+ }
+
+ public String getMessage() {
+ return getMessage(super.getMessage(), locations);
+ }
+
+ public void addLocation(Location loc) {
+ if (LocationUtils.isUnknown(loc))
+ return;
+
+ if (locations == null) {
+ this.locations = new ArrayList(1); // Start small
+ }
+ locations.add(LocationImpl.get(loc));
+ }
+}
Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/location/LocatedException.java
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/location/LocatedRuntimeException.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/location/LocatedRuntimeException.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/location/LocatedRuntimeException.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/location/LocatedRuntimeException.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * 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 org.apache.struts.flow.core.location;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.commons.lang.exception.NestableRuntimeException;
+
+/**
+ * A cascading and located <code>RuntimeException</code>. It is also {@link MultiLocatable} to easily build
+ * location stack traces.
+ * <p>
+ * If a <code>LocatedRuntimeException</code> is built with a location and a cause which is also a
+ * <code>LocatedRuntimeException</code>, then the default behavior is to add the location to the cause
+ * exception and immediately rethrow the cause. This avoids exception nesting and builds a location
+ * stack.
+ *
+ * @since 2.1.8
+ * @version $Id: LocatedRuntimeException.java 290845 2005-09-21 22:04:27Z sylvain $
+ */
+public class LocatedRuntimeException extends NestableRuntimeException implements LocatableException, MultiLocatable {
+
+ private List locations;
+
+ public LocatedRuntimeException(String message) {
+ this(message, null, null, true);
+ }
+
+ public LocatedRuntimeException(String message, Throwable cause) throws LocatedRuntimeException {
+ this(message, cause, null, true);
+ }
+
+ public LocatedRuntimeException(String message, Location location) {
+ this(message, null, location, true);
+ }
+
+ public LocatedRuntimeException(String message, Throwable cause, Location location) throws LocatedRuntimeException {
+ this(message, cause, location, true);
+ }
+
+ public LocatedRuntimeException(String message, Throwable cause, Location location, boolean rethrowLocated)
+ throws LocatedRuntimeException {
+ super(message, cause);
+ if (rethrowLocated && cause instanceof LocatedRuntimeException) {
+ LocatedRuntimeException lreCause = (LocatedRuntimeException)cause;
+ lreCause.addLocation(location);
+ // Rethrow the cause
+ throw lreCause;
+ }
+
+ LocatedException.ensureCauseChainIsSet(cause);
+ LocatedException.addCauseLocations(this, cause);
+ addLocation(location);
+ }
+
+ public Location getLocation() {
+ return locations == null ? null : (Location)locations.get(0);
+ }
+
+ public List getLocations() {
+ return locations == null ? Collections.EMPTY_LIST : locations;
+ }
+
+ public String getRawMessage() {
+ return super.getMessage();
+ }
+
+ public String getMessage() {
+ return LocatedException.getMessage(super.getMessage(), locations);
+ }
+
+ public void addLocation(Location loc) {
+ if (LocationUtils.isUnknown(loc))
+ return;
+
+ if (locations == null) {
+ this.locations = new ArrayList(1); // Start small
+ }
+ locations.add(LocationImpl.get(loc));
+ }
+}
Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/location/LocatedRuntimeException.java
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/location/Location.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/location/Location.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/location/Location.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/location/Location.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * 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 org.apache.struts.flow.core.location;
+
+
+/**
+ * A location in a resource. The location is composed of the URI of the resource, and
+ * the line and column numbers within that resource (when available), along with a description.
+ * <p>
+ * Locations are mostly provided by {@link Locatable}s objects.
+ *
+ * @since 2.1.8
+ * @version $Id: Location.java 233343 2005-08-18 18:06:44Z sylvain $
+ */
+public interface Location {
+
+ /**
+ * Constant for unknown locations.
+ */
+ public static final Location UNKNOWN = LocationImpl.UNKNOWN;
+
+ /**
+ * Get the description of this location
+ *
+ * @return the description (can be <code>null</code>)
+ */
+ public String getDescription();
+
+ /**
+ * Get the URI of this location
+ *
+ * @return the URI (<code>null</code> if unknown).
+ */
+ public String getURI();
+ /**
+ * Get the line number of this location
+ *
+ * @return the line number (<code>-1</code> if unknown)
+ */
+ public int getLineNumber();
+
+ /**
+ * Get the column number of this location
+ *
+ * @return the column number (<code>-1</code> if unknown)
+ */
+ public int getColumnNumber();
+
+}
Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/location/Location.java
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/location/LocationAttributes.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/location/LocationAttributes.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/location/LocationAttributes.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/location/LocationAttributes.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,349 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * 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 org.apache.struts.flow.core.location;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * A class to handle location information stored in attributes.
+ * These attributes are typically setup using {@link org.apache.struts.flow.core.location.LocationAttributes.Pipe}
+ * which augments the SAX stream with additional attributes, e.g.:
+ * <pre>
+ * <root xmlns:loc="http://apache.org/cocoon/location"
+ * loc:src="file://path/to/file.xml"
+ * loc:line="1" loc:column="1">
+ * <foo loc:src="file://path/to/file.xml" loc:line="2" loc:column="3"/>
+ * </root>
+ * </pre>
+ *
+ * @see org.apache.struts.flow.core.location.LocationAttributes.Pipe
+ * @since 2.1.8
+ * @version $Id: LocationAttributes.java 328390 2005-10-25 15:37:05Z sylvain $
+ */
+public class LocationAttributes {
+ /** Prefix for the location namespace */
+ public static final String PREFIX = "loc";
+ /** Namespace URI for location attributes */
+ public static final String URI = "http://apache.org/cocoon/location";
+
+ /** Attribute name for the location URI */
+ public static final String SRC_ATTR = "src";
+ /** Attribute name for the line number */
+ public static final String LINE_ATTR = "line";
+ /** Attribute name for the column number */
+ public static final String COL_ATTR = "column";
+
+ /** Attribute qualified name for the location URI */
+ public static final String Q_SRC_ATTR = "loc:src";
+ /** Attribute qualified name for the line number */
+ public static final String Q_LINE_ATTR = "loc:line";
+ /** Attribute qualified name for the column number */
+ public static final String Q_COL_ATTR = "loc:column";
+
+ // Private constructor, we only have static methods
+ private LocationAttributes() {
+ // Nothing
+ }
+
+ /**
+ * Add location attributes to a set of SAX attributes.
+ *
+ * @param locator the <code>Locator</code> (can be null)
+ * @param attrs the <code>Attributes</code> where locator information should be added
+ * @return
+ */
+ public static Attributes addLocationAttributes(Locator locator, Attributes attrs) {
+ if (locator == null || attrs.getIndex(URI, SRC_ATTR) != -1) {
+ // No location information known, or already has it
+ return attrs;
+ }
+
+ // Get an AttributeImpl so that we can add new attributes.
+ AttributesImpl newAttrs = attrs instanceof AttributesImpl ?
+ (AttributesImpl)attrs : new AttributesImpl(attrs);
+
+ newAttrs.addAttribute(URI, SRC_ATTR, Q_SRC_ATTR, "CDATA", locator.getSystemId());
+ newAttrs.addAttribute(URI, LINE_ATTR, Q_LINE_ATTR, "CDATA", Integer.toString(locator.getLineNumber()));
+ newAttrs.addAttribute(URI, COL_ATTR, Q_COL_ATTR, "CDATA", Integer.toString(locator.getColumnNumber()));
+
+ return newAttrs;
+ }
+
+ /**
+ * Returns the {@link Location} of an element (SAX flavor).
+ *
+ * @param attrs the element's attributes that hold the location information
+ * @param description a description for the location (can be null)
+ * @return a {@link Location} object
+ */
+ public static Location getLocation(Attributes attrs, String description) {
+ String src = attrs.getValue(URI, SRC_ATTR);
+ if (src == null) {
+ return Location.UNKNOWN;
+ }
+
+ return new LocationImpl(description, src, getLine(attrs), getColumn(attrs));
+ }
+
+ /**
+ * Returns the location of an element (SAX flavor). If the location is to be kept
+ * into an object built from this element, consider using {@link #getLocation(Attributes)}
+ * and the {@link Locatable} interface.
+ *
+ * @param attrs the element's attributes that hold the location information
+ * @return a location string as defined by {@link Location#toString()}.
+ */
+ public static String getLocationString(Attributes attrs) {
+ String src = attrs.getValue(URI, SRC_ATTR);
+ if (src == null) {
+ return LocationUtils.UNKNOWN_STRING;
+ }
+
+ return src + ":" + attrs.getValue(URI, LINE_ATTR) + ":" + attrs.getValue(URI, COL_ATTR);
+ }
+
+ /**
+ * Returns the URI of an element (SAX flavor)
+ *
+ * @param attrs the element's attributes that hold the location information
+ * @return the element's URI or "<code>[unknown location]</code>" if <code>attrs</code>
+ * has no location information.
+ */
+ public static String getURI(Attributes attrs) {
+ String src = attrs.getValue(URI, SRC_ATTR);
+ return src != null ? src : LocationUtils.UNKNOWN_STRING;
+ }
+
+ /**
+ * Returns the line number of an element (SAX flavor)
+ *
+ * @param attrs the element's attributes that hold the location information
+ * @return the element's line number or <code>-1</code> if <code>attrs</code>
+ * has no location information.
+ */
+ public static int getLine(Attributes attrs) {
+ String line = attrs.getValue(URI, LINE_ATTR);
+ return line != null ? Integer.parseInt(line) : -1;
+ }
+
+ /**
+ * Returns the column number of an element (SAX flavor)
+ *
+ * @param attrs the element's attributes that hold the location information
+ * @return the element's column number or <code>-1</code> if <code>attrs</code>
+ * has no location information.
+ */
+ public static int getColumn(Attributes attrs) {
+ String col = attrs.getValue(URI, COL_ATTR);
+ return col != null ? Integer.parseInt(col) : -1;
+ }
+
+ /**
+ * Returns the {@link Location} of an element (DOM flavor).
+ *
+ * @param attrs the element that holds the location information
+ * @param description a description for the location (if <code>null</code>, the element's name is used)
+ * @return a {@link Location} object
+ */
+ public static Location getLocation(Element elem, String description) {
+ Attr srcAttr = elem.getAttributeNodeNS(URI, SRC_ATTR);
+ if (srcAttr == null) {
+ return Location.UNKNOWN;
+ }
+
+ return new LocationImpl(description == null ? elem.getNodeName() : description,
+ srcAttr.getValue(), getLine(elem), getColumn(elem));
+ }
+
+ /**
+ * Same as <code>getLocation(elem, null)</code>.
+ */
+ public static Location getLocation(Element elem) {
+ return getLocation(elem, null);
+ }
+
+
+ /**
+ * Returns the location of an element that has been processed by this pipe (DOM flavor).
+ * If the location is to be kept into an object built from this element, consider using
+ * {@link #getLocation(Element)} and the {@link Locatable} interface.
+ *
+ * @param elem the element that holds the location information
+ * @return a location string as defined by {@link Location#toString()}.
+ */
+ public static String getLocationString(Element elem) {
+ Attr srcAttr = elem.getAttributeNodeNS(URI, SRC_ATTR);
+ if (srcAttr == null) {
+ return LocationUtils.UNKNOWN_STRING;
+ }
+
+ return srcAttr.getValue() + ":" + elem.getAttributeNS(URI, LINE_ATTR) + ":" + elem.getAttributeNS(URI, COL_ATTR);
+ }
+
+ /**
+ * Returns the URI of an element (DOM flavor)
+ *
+ * @param elem the element that holds the location information
+ * @return the element's URI or "<code>[unknown location]</code>" if <code>elem</code>
+ * has no location information.
+ */
+ public static String getURI(Element elem) {
+ Attr attr = elem.getAttributeNodeNS(URI, SRC_ATTR);
+ return attr != null ? attr.getValue() : LocationUtils.UNKNOWN_STRING;
+ }
+
+ /**
+ * Returns the line number of an element (DOM flavor)
+ *
+ * @param elem the element that holds the location information
+ * @return the element's line number or <code>-1</code> if <code>elem</code>
+ * has no location information.
+ */
+ public static int getLine(Element elem) {
+ Attr attr = elem.getAttributeNodeNS(URI, LINE_ATTR);
+ return attr != null ? Integer.parseInt(attr.getValue()) : -1;
+ }
+
+ /**
+ * Returns the column number of an element (DOM flavor)
+ *
+ * @param elem the element that holds the location information
+ * @return the element's column number or <code>-1</code> if <code>elem</code>
+ * has no location information.
+ */
+ public static int getColumn(Element elem) {
+ Attr attr = elem.getAttributeNodeNS(URI, COL_ATTR);
+ return attr != null ? Integer.parseInt(attr.getValue()) : -1;
+ }
+
+ /**
+ * Remove the location attributes from a DOM element.
+ *
+ * @param elem the element to remove the location attributes from.
+ * @param recurse if <code>true</code>, also remove location attributes on descendant elements.
+ */
+ public static void remove(Element elem, boolean recurse) {
+ elem.removeAttributeNS(URI, SRC_ATTR);
+ elem.removeAttributeNS(URI, LINE_ATTR);
+ elem.removeAttributeNS(URI, COL_ATTR);
+ if (recurse) {
+ NodeList children = elem.getChildNodes();
+ for (int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ if (child.getNodeType() == Node.ELEMENT_NODE) {
+ remove((Element)child, recurse);
+ }
+ }
+ }
+ }
+
+ /**
+ * A SAX filter that adds the information available from the <code>Locator</code> as attributes.
+ * The purpose of having location as attributes is to allow this information to survive transformations
+ * of the document (an XSL could copy these attributes over) or conversion of SAX events to a DOM.
+ * <p>
+ * The location is added as 3 attributes in a specific namespace to each element.
+ * <pre>
+ * <root xmlns:loc="http://apache.org/cocoon/location"
+ * loc:src="file://path/to/file.xml"
+ * loc:line="1" loc:column="1">
+ * <foo loc:src="file://path/to/file.xml" loc:line="2" loc:column="3"/>
+ * </root>
+ * </pre>
+ * <strong>Note:</strong> Although this adds a lot of information to the serialized form of the document,
+ * the overhead in SAX events is not that big, as attribute names are interned, and all <code>src</code>
+ * attributes point to the same string.
+ *
+ * @see org.apache.struts.flow.core.location.LocationAttributes
+ * @since 2.1.8
+ */
+ public static class Pipe implements ContentHandler {
+
+ private Locator locator;
+
+ private ContentHandler nextHandler;
+
+ /**
+ * Create a filter. It has to be chained to another handler to be really useful.
+ */
+ public Pipe() {
+ }
+
+ /**
+ * Create a filter that is chained to another handler.
+ * @param next the next handler in the chain.
+ */
+ public Pipe(ContentHandler next) {
+ nextHandler = next;
+ }
+
+ public void setDocumentLocator(Locator locator) {
+ this.locator = locator;
+ nextHandler.setDocumentLocator(locator);
+ }
+
+ public void startDocument() throws SAXException {
+ nextHandler.startDocument();
+ nextHandler.startPrefixMapping(LocationAttributes.PREFIX, LocationAttributes.URI);
+ }
+
+ public void endDocument() throws SAXException {
+ endPrefixMapping(LocationAttributes.PREFIX);
+ nextHandler.endDocument();
+ }
+
+ public void startElement(String uri, String loc, String raw, Attributes attrs) throws SAXException {
+ // Add location attributes to the element
+ nextHandler.startElement(uri, loc, raw, LocationAttributes.addLocationAttributes(locator, attrs));
+ }
+
+ public void endElement(String arg0, String arg1, String arg2) throws SAXException {
+ nextHandler.endElement(arg0, arg1, arg2);
+ }
+
+ public void startPrefixMapping(String arg0, String arg1) throws SAXException {
+ nextHandler.startPrefixMapping(arg0, arg1);
+ }
+
+ public void endPrefixMapping(String arg0) throws SAXException {
+ nextHandler.endPrefixMapping(arg0);
+ }
+
+ public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
+ nextHandler.characters(arg0, arg1, arg2);
+ }
+
+ public void ignorableWhitespace(char[] arg0, int arg1, int arg2) throws SAXException {
+ nextHandler.ignorableWhitespace(arg0, arg1, arg2);
+ }
+
+ public void processingInstruction(String arg0, String arg1) throws SAXException {
+ nextHandler.processingInstruction(arg0, arg1);
+ }
+
+ public void skippedEntity(String arg0) throws SAXException {
+ nextHandler.skippedEntity(arg0);
+ }
+ }
+}
Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/location/LocationAttributes.java
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/location/LocationImpl.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/location/LocationImpl.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/location/LocationImpl.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/location/LocationImpl.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * 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 org.apache.struts.flow.core.location;
+
+import java.io.Serializable;
+
+import org.apache.commons.lang.ObjectUtils;
+
+/**
+ * A simple immutable and serializable implementation of {@link Location}.
+ *
+ * @since 2.1.8
+ * @version $Id: LocationImpl.java 280946 2005-09-14 21:43:05Z sylvain $
+ */
+public class LocationImpl implements Location, Serializable {
+ private final String uri;
+ private final int line;
+ private final int column;
+ private final String description;
+
+ // Package private: outside this package, use Location.UNKNOWN.
+ static final LocationImpl UNKNOWN = new LocationImpl(null, null, -1, -1);
+
+ /**
+ * Build a location for a given URI, with unknown line and column numbers.
+ *
+ * @param uri the resource URI
+ */
+ public LocationImpl(String description, String uri) {
+ this(description, uri, -1, -1);
+ }
+
+ /**
+ * Build a location for a given URI and line and columb numbers.
+ *
+ * @param uri the resource URI
+ * @param line the line number (starts at 1)
+ * @param column the column number (starts at 1)
+ */
+ public LocationImpl(String description, String uri, int line, int column) {
+ if (uri == null || uri.length() == 0) {
+ this.uri = null;
+ this.line = -1;
+ this.column = -1;
+ } else {
+ this.uri = uri;
+ this.line = line;
+ this.column = column;
+ }
+
+ if (description != null && description.length() == 0) {
+ description = null;
+ }
+ this.description = description;
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param location the location to be copied
+ */
+ public LocationImpl(Location location) {
+ this(location.getDescription(), location.getURI(), location.getLineNumber(), location.getColumnNumber());
+ }
+
+ /**
+ * Create a location from an existing one, but with a different description
+ */
+ public LocationImpl(String description, Location location) {
+ this(description, location.getURI(), location.getLineNumber(), location.getColumnNumber());
+ }
+
+ /**
+ * Obtain a <code>LocationImpl</code> from a {@link Location}. If <code>location</code> is
+ * already a <code>LocationImpl</code>, it is returned, otherwise it is copied.
+ * <p>
+ * This method is useful when an immutable and serializable location is needed, such as in locatable
+ * exceptions.
+ *
+ * @param location the location
+ * @return an immutable and serializable version of <code>location</code>
+ */
+ public static LocationImpl get(Location location) {
+ if (location instanceof LocationImpl) {
+ return (LocationImpl)location;
+ } else if (location == null) {
+ return UNKNOWN;
+ } else {
+ return new LocationImpl(location);
+ }
+ }
+
+ /**
+ * Get the description of this location
+ *
+ * @return the description (can be <code>null</code>)
+ */
+ public String getDescription() {
+ return this.description;
+ }
+
+ /**
+ * Get the URI of this location
+ *
+ * @return the URI (<code>null</code> if unknown).
+ */
+ public String getURI() {
+ return this.uri;
+ }
+
+ /**
+ * Get the line number of this location
+ *
+ * @return the line number (<code>-1</code> if unknown)
+ */
+ public int getLineNumber() {
+ return this.line;
+ }
+
+ /**
+ * Get the column number of this location
+ *
+ * @return the column number (<code>-1</code> if unknown)
+ */
+ public int getColumnNumber() {
+ return this.column;
+ }
+
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+
+ if (obj instanceof Location) {
+ Location other = (Location)obj;
+ return this.line == other.getLineNumber() && this.column == other.getColumnNumber()
+ && ObjectUtils.equals(this.uri, other.getURI())
+ && ObjectUtils.equals(this.description, other.getDescription());
+ }
+
+ return false;
+ }
+
+ public int hashCode() {
+ int hash = line ^ column;
+ if (uri != null) hash ^= uri.hashCode();
+ if (description != null) hash ^= description.hashCode();
+
+ return hash;
+ }
+
+ public String toString() {
+ return LocationUtils.toString(this);
+ }
+
+ /**
+ * Ensure serialized unknown location resolve to {@link Location#UNKNOWN}.
+ */
+ private Object readResolve() {
+ return this.equals(Location.UNKNOWN) ? Location.UNKNOWN : this;
+ }
+}
Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/location/LocationImpl.java
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/location/LocationUtils.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/location/LocationUtils.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/location/LocationUtils.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/location/LocationUtils.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,271 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * 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 org.apache.struts.flow.core.location;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.TransformerException;
+
+import org.xml.sax.Locator;
+import org.xml.sax.SAXParseException;
+
+/**
+ * Location-related utility methods.
+ *
+ * @version $Id: LocationUtils.java 280946 2005-09-14 21:43:05Z sylvain $
+ * @since 2.1.8
+ */
+public class LocationUtils {
+
+ /**
+ * The string representation of an unknown location: "<code>[unknown location]</code>".
+ */
+ public static final String UNKNOWN_STRING = "[unknown location]";
+
+ private static List finders = new ArrayList();
+
+ /**
+ * An finder or object locations
+ *
+ * @since 2.1.8
+ */
+ public interface LocationFinder {
+ /**
+ * Get the location of an object
+ * @param obj the object for which to find a location
+ * @param description and optional description to be added to the object's location
+ * @return the object's location or <code>null</code> if object's class isn't handled
+ * by this finder.
+ */
+ Location getLocation(Object obj, String description);
+ }
+
+ private LocationUtils() {
+ // Forbid instanciation
+ }
+
+ /**
+ * Builds a string representation of a location, in the
+ * "<code><em>descripton</em> - <em>uri</em>:<em>line</em>:<em>column</em></code>"
+ * format (e.g. "<code>foo - file://path/to/file.xml:3:40</code>"). For {@link Location#UNKNOWN an unknown location}, returns
+ * {@link #UNKNOWN_STRING}.
+ *
+ * @return the string representation
+ */
+ public static String toString(Location location) {
+ StringBuffer result = new StringBuffer();
+
+ String description = location.getDescription();
+ if (description != null) {
+ result.append(description).append(" - ");
+ }
+
+ String uri = location.getURI();
+ if (uri != null) {
+ result.append(uri).append(':').append(location.getLineNumber()).append(':').append(location.getColumnNumber());
+ } else {
+ result.append(UNKNOWN_STRING);
+ }
+
+ return result.toString();
+ }
+
+ /**
+ * Parse a location string of the form "<code><em>uri</em>:<em>line</em>:<em>column</em></code>" (e.g.
+ * "<code>path/to/file.xml:3:40</code>") to a Location object. Additionally, a description may
+ * also optionally be present, separated with an hyphen (e.g. "<code>foo - path/to/file.xml:3.40</code>").
+ *
+ * @param text the text to parse
+ * @return the location (possibly <code>null</code> if text was null or in an incorrect format)
+ */
+ public static LocationImpl parse(String text) throws IllegalArgumentException {
+ if (text == null || text.length() == 0) {
+ return null;
+ }
+
+ // Do we have a description?
+ String description;
+ int uriStart = text.lastIndexOf(" - "); // lastIndexOf to allow the separator to be in the description
+ if (uriStart > -1) {
+ description = text.substring(0, uriStart);
+ uriStart += 3; // strip " - "
+ } else {
+ description = null;
+ uriStart = 0;
+ }
+
+ try {
+ int colSep = text.lastIndexOf(':');
+ if (colSep > -1) {
+ int column = Integer.parseInt(text.substring(colSep + 1));
+
+ int lineSep = text.lastIndexOf(':', colSep - 1);
+ if (lineSep > -1) {
+ int line = Integer.parseInt(text.substring(lineSep + 1, colSep));
+ return new LocationImpl(description, text.substring(uriStart, lineSep), line, column);
+ }
+ } else {
+ // unkonwn?
+ if (text.endsWith(UNKNOWN_STRING)) {
+ return LocationImpl.UNKNOWN;
+ }
+ }
+ } catch(Exception e) {
+ // Ignore: handled below
+ }
+
+ return LocationImpl.UNKNOWN;
+ }
+
+ /**
+ * Checks if a location is known, i.e. it is not null nor equal to {@link Location#UNKNOWN}.
+ *
+ * @param location the location to check
+ * @return <code>true</code> if the location is known
+ */
+ public static boolean isKnown(Location location) {
+ return location != null && !Location.UNKNOWN.equals(location);
+ }
+
+ /**
+ * Checks if a location is unknown, i.e. it is either null or equal to {@link Location#UNKNOWN}.
+ *
+ * @param location the location to check
+ * @return <code>true</code> if the location is unknown
+ */
+ public static boolean isUnknown(Location location) {
+ return location == null || Location.UNKNOWN.equals(location);
+ }
+
+ /**
+ * Add a {@link LocationFinder} to the list of finders that will be queried for an object's
+ * location by {@link #getLocation(Object, String)}.
+ * <p>
+ * <b>Important:</b> LocationUtils internally stores a weak reference to the finder. This
+ * avoids creating strong links between the classloader holding this class and the finder's
+ * classloader, which can cause some weird memory leaks if the finder's classloader is to
+ * be reloaded. Therefore, you <em>have</em> to keep a strong reference to the finder in the
+ * calling code, e.g.:
+ * <pre>
+ * private static LocationUtils.LocationFinder myFinder =
+ * new LocationUtils.LocationFinder() {
+ * public Location getLocation(Object obj, String desc) {
+ * ...
+ * }
+ * };
+ *
+ * static {
+ * LocationUtils.addFinder(myFinder);
+ * }
+ * </pre>
+ *
+ * @param finder the location finder to add
+ */
+ public static void addFinder(LocationFinder finder) {
+ if (finder == null) {
+ return;
+ }
+
+ synchronized(LocationFinder.class) {
+ // Update a clone of the current finder list to avoid breaking
+ // any iteration occuring in another thread.
+ List newFinders = new ArrayList(finders);
+ newFinders.add(new WeakReference(finder));
+ finders = newFinders;
+ }
+ }
+
+ /**
+ * Get the location of an object. Some well-known located classes built in the JDK are handled
+ * by this method. Handling of other located classes can be handled by adding new location finders.
+ *
+ * @param obj the object of which to get the location
+ * @return the object's location, or {@link Location#UNKNOWN} if no location could be found
+ */
+ public static Location getLocation(Object obj) {
+ return getLocation(obj, null);
+ }
+
+ /**
+ * Get the location of an object. Some well-known located classes built in the JDK are handled
+ * by this method. Handling of other located classes can be handled by adding new location finders.
+ *
+ * @param obj the object of which to get the location
+ * @param description an optional description of the object's location, used if a Location object
+ * has to be created.
+ * @return the object's location, or {@link Location#UNKNOWN} if no location could be found
+ */
+ public static Location getLocation(Object obj, String description) {
+ if (obj instanceof Locatable) {
+ return ((Locatable)obj).getLocation();
+ }
+
+ // Check some well-known locatable exceptions
+ if (obj instanceof SAXParseException) {
+ SAXParseException spe = (SAXParseException)obj;
+ if (spe.getSystemId() != null) {
+ return new LocationImpl(description, spe.getSystemId(), spe.getLineNumber(), spe.getColumnNumber());
+ } else {
+ return Location.UNKNOWN;
+ }
+ }
+
+ if (obj instanceof TransformerException) {
+ TransformerException ex = (TransformerException)obj;
+ SourceLocator locator = ex.getLocator();
+ if (locator != null && locator.getSystemId() != null) {
+ return new LocationImpl(description, locator.getSystemId(), locator.getLineNumber(), locator.getColumnNumber());
+ } else {
+ return Location.UNKNOWN;
+ }
+ }
+
+ if (obj instanceof Locator) {
+ Locator locator = (Locator)obj;
+ if (locator.getSystemId() != null) {
+ return new LocationImpl(description, locator.getSystemId(), locator.getLineNumber(), locator.getColumnNumber());
+ } else {
+ return Location.UNKNOWN;
+ }
+ }
+
+ List currentFinders = finders; // Keep the current list
+ int size = currentFinders.size();
+ for (int i = 0; i < size; i++) {
+ WeakReference ref = (WeakReference)currentFinders.get(i);
+ LocationFinder finder = (LocationFinder)ref.get();
+ if (finder == null) {
+ // This finder was garbage collected: update finders
+ synchronized(LocationFinder.class) {
+ // Update a clone of the current list to avoid breaking current iterations
+ List newFinders = new ArrayList(finders);
+ newFinders.remove(ref);
+ finders = newFinders;
+ }
+ }
+
+ Location result = finder.getLocation(obj, description);
+ if (result != null) {
+ return result;
+ }
+ }
+
+ return Location.UNKNOWN;
+ }
+}
Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/location/LocationUtils.java
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/location/MultiLocatable.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/location/MultiLocatable.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/location/MultiLocatable.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/location/MultiLocatable.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,39 @@
+package org.apache.struts.flow.core.location;
+
+import java.util.List;
+
+/**
+ * An extension of {@link Location} for classes that can hold a list of locations.
+ * It will typically be used to build location stacks.
+ * <p>
+ * The <em>first</em> location of the collection returned by {@link #getLocations()} should be
+ * be identical to the result of {@link org.apache.struts.flow.core.location.Locatable#getLocation()}.
+ * <p>
+ * If the list of locations designates a call stack, then its first element should be the deepmost
+ * location of this stack. This is consistent with the need for <code>getLocation()</code> to
+ * return the most precise location.
+ *
+ * @since 2.1.8
+ * @version $Id: MultiLocatable.java 233343 2005-08-18 18:06:44Z sylvain $
+ */
+public interface MultiLocatable extends Locatable {
+
+ /**
+ * Return the list of locations.
+ *
+ * @return a list of locations, possibly empty but never null.
+ */
+ public List getLocations();
+
+ /**
+ * Add a location to the current list of locations.
+ * <p>
+ * Implementations are free to filter locations that can be added (e.g. {@link Location#UNKNOWN}),
+ * and there is therefore no guarantee that the given location will actually be added to the list.
+ * Filtered locations are silently ignored.
+ *
+ * @param location the location to be added.
+ */
+ public void addLocation(Location location);
+
+}
Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/location/MultiLocatable.java
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/location/package.html
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/location/package.html?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/location/package.html (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/location/package.html Sat Nov 26 23:10:08 2005
@@ -0,0 +1,3 @@
+<html>
+ <body>Classes and utilities used to track location information.</body>
+</html>
\ No newline at end of file
Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/ModifiableSource.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/source/ModifiableSource.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/source/ModifiableSource.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/source/ModifiableSource.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2002-2004 The Apache Software Foundation
+ * 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 org.apache.struts.flow.core.source;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * A {@link Source} that can be written to.
+ * <p>
+ * As far a possible, implementations should provide a kind of transaction or
+ * buffering of data written to the source. This is especially important in
+ * stream-based systems such as Cocoon where an error that occurs during the
+ * processing should lead to cancelling data written to the source.
+ * <p>
+ * This is the role of the {@link #canCancel(OutputStream)} and
+ * {@link #cancel(OutputStream)} methods.
+ *
+ * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
+ * @version CVS $Revision: 1.4 $ $Date: 2004/02/28 11:47:26 $
+ */
+public interface ModifiableSource
+ extends Source
+{
+ /**
+ * Return an {@link OutputStream} to write to.
+ *
+ * The returned stream must be closed or cancelled by the calling code.
+ */
+ OutputStream getOutputStream() throws IOException;
+
+ /**
+ * Delete the source
+ */
+ void delete() throws SourceException;
+
+ /**
+ * Can the data sent to an <code>OutputStream</code> returned by
+ * {@link #getOutputStream()} be cancelled ?
+ *
+ * @return true if the stream can be cancelled
+ */
+ boolean canCancel(OutputStream stream);
+
+ /**
+ * Cancel the data sent to an <code>OutputStream</code> returned by
+ * {@link #getOutputStream()}. Cancelling the stream will also close it.
+ *
+ * <p>After cancelling, the stream should no longer be used.</p>
+ */
+ void cancel(OutputStream stream) throws IOException;
+
+}
Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/ModifiableSource.java
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/ModifiableTraversableSource.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/source/ModifiableTraversableSource.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/source/ModifiableTraversableSource.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/source/ModifiableTraversableSource.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2002-2004 The Apache Software Foundation
+ * 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 org.apache.struts.flow.core.source;
+
+/**
+ * A modifiable traversable source. This adds to {@link ModifiableSource} the
+ * ability to create a directory.
+ *
+ * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
+ * @version CVS $Revision: 1.4 $ $Date: 2004/02/28 11:47:26 $
+ */
+public interface ModifiableTraversableSource extends ModifiableSource, TraversableSource
+{
+ /**
+ * If it doesn't already exist, ensure this source is traversable
+ * (equivalent to <code>File.mkdirs()</code>)
+ * <p>
+ * If the source already exists, this method does nothing if it's already
+ * traversable, and fails otherwise.
+ */
+ public void makeCollection() throws SourceException;
+
+}
+
+
Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/ModifiableTraversableSource.java
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/MoveableSource.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/source/MoveableSource.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/source/MoveableSource.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/source/MoveableSource.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2002-2004 The Apache Software Foundation
+ * 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 org.apache.struts.flow.core.source;
+
+
+/**
+ * This class marks a source to be able to moved and copied to
+ * serveral other locations. This class should only be used if
+ * the implementations details should be hidden, otherwise
+ * the class SourceUtils can be used.
+ *
+ * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
+ * @version CVS $Id: MoveableSource.java,v 1.5 2004/02/28 11:47:26 cziegeler Exp $
+ */
+public interface MoveableSource extends Source
+{
+
+ /**
+ * Copy the current source to a specified destination.
+ *
+ * @param destination Destination of the source.
+ *
+ * @throws SourceException If an exception occurs during
+ * the copy.
+ */
+ void copyTo(Source destination) throws SourceException;
+
+ /**
+ * Move the current source to a specified destination.
+ *
+ * @param destination Destination of the source.
+ *
+ * @throws SourceException If an exception occurs during
+ * the move.
+ */
+ void moveTo(Source destination) throws SourceException;
+}
Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/MoveableSource.java
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/Source.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/source/Source.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/source/Source.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/source/Source.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2002-2004 The Apache Software Foundation
+ * 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 org.apache.struts.flow.core.source;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * This interface provides a simple interface for accessing a source of data.
+ * <p>
+ * When the <code>Source</code> object is no longer needed
+ * it must be released using the {@link SourceResolver}. This is very similar to
+ * looking up components from a <code>ServiceSelector</code>.
+ * In fact a source object can implement most lifecycle interfaces
+ * like Composable, Initializable, Disposable etc.
+ * <p>
+ * The data content can be constant or change over time.
+ * Using the {@link #getInputStream()} method you get always the up-to-date content.
+ * <p>
+ * If you want to track changes of the source object, this interface
+ * offers you some support for it by providing a SourceValidity object.
+ * <p>
+ * How does the caching work?
+ * The first time you get a Source object, you simply ask
+ * it for it's content via getInputStream() and then get the validity
+ * object by invoking getValidity. (Further calls to getValidity always
+ * return the same object! This is not updated!)
+ * The caching algorithm can now store this validity object together
+ * with the system identifier of the source.
+ * The next time, the caching algorithm wants to check if the cached
+ * content is still valid. It has a validity object already to check
+ * against.
+ * <p>
+ * If it is still the same Source than the first time, you
+ * have to call refresh() in order to discard the stored validity
+ * in the Source object. If it is a new Source object,
+ * calling refresh() should do no harm.
+ * After that an up-to-date validity object can retrieved by calling
+ * getValidity(). This can be used to test if the content is still valid
+ * as discribed in the source validity documentation.
+ * If the content is still valid, the cache knows what to do, if not,
+ * the new content can be get using getInputStream().
+ * So either after a call to getValidity() or the getInputStream the
+ * validity object must be the same until refresh is called!
+ *
+ * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
+ * @version CVS $Revision: 1.4 $ $Date: 2004/02/28 11:47:26 $
+ */
+public interface Source
+{
+ /**
+ * Does this source exist ?
+ *
+ * @return true if the source exists
+ */
+ boolean exists();
+
+ /**
+ * Return an <code>InputStream</code> to read from the source.
+ * This is the data at the point of invocation of this method,
+ * so if this is Modifiable, you might get different content
+ * from two different invocations.
+ *
+ * The returned stream must be closed by the calling code.
+ *
+ * @return the <code>InputStream</code> to read data from (never <code>null</code>).
+ * @throws IOException if some I/O problem occurs.
+ * @throws SourceNotFoundException if the source doesn't exist.
+ */
+ InputStream getInputStream()
+ throws IOException, SourceNotFoundException;
+
+ /**
+ * Get the absolute URI for this source.
+ *
+ * @return the source URI.
+ */
+ String getURI();
+
+ /**
+ * Return the URI scheme identifier, i.e. the part preceding the fist ':' in the URI
+ * (see <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>).
+ * <p>
+ * This scheme can be used to get the {@link SourceFactory} responsible for this object.
+ *
+ * @return the URI scheme.
+ */
+ String getScheme();
+
+ /**
+ * Get the Validity object. This can either wrap the last modification date or
+ * some expiry information or anything else describing this object's validity.
+ * <p>
+ * If it is currently not possible to calculate such an information,
+ * <code>null</code> is returned.
+ *
+ * @return the validity, or <code>null</code>.
+ */
+ SourceValidity getValidity();
+
+ /**
+ * Refresh the content of this object after the underlying data content has changed.
+ * <p>
+ * Some implementations may cache some values to speedup sucessive calls. Refreshing
+ * ensures you get the latest information.
+ */
+ void refresh();
+
+ /**
+ * Get the mime-type of the content described by this object.
+ * If the source is not able to determine the mime-type by itself
+ * this can be <code>null</code>.
+ *
+ * @return the source's mime-type or <code>null</code>.
+ */
+ String getMimeType();
+
+ /**
+ * Get the content length of this source's content or -1 if the length is
+ * unknown.
+ *
+ * @return the source's content length or -1.
+ */
+ long getContentLength();
+
+ /**
+ * Get the last modification date of this source. The date is
+ * measured in milliseconds since the epoch (00:00:00 GMT, January 1, 1970),
+ * and is <code>0</code> if it's unknown.
+ *
+ * @return the last modification date or <code>0</code>.
+ */
+ long getLastModified();
+
+}
Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/Source.java
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/SourceException.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/source/SourceException.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/source/SourceException.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/source/SourceException.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2002-2004 The Apache Software Foundation
+ * 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 org.apache.struts.flow.core.source;
+
+import java.io.IOException;
+
+/**
+ * This Exception is thrown every time there is a problem in processing
+ * a source.
+ *
+ * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
+ * @version CVS $Revision: 1.4 $ $Date: 2004/02/28 11:47:26 $
+ */
+public class SourceException
+ extends IOException
+{
+ /**
+ * The Throwable that caused this exception to be thrown.
+ */
+ private final Throwable m_throwable;
+
+ /**
+ * Construct a new <code>SourceException</code> instance.
+ *
+ * @param message the detail message for this exception.
+ */
+ public SourceException( final String message )
+ {
+ this( message, null );
+ }
+
+ /**
+ * Construct a new <code>SourceException</code> instance.
+ *
+ * @param message the detail message for this exception.
+ * @param throwable the root cause of the exception.
+ */
+ public SourceException( final String message, final Throwable throwable )
+ {
+ super( message );
+ m_throwable = throwable;
+ }
+
+ /**
+ * Retrieve the cause of the exception.
+ *
+ * @return the cause.
+ */
+ public final Throwable getCause()
+ {
+ return m_throwable;
+ }
+}
Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/SourceException.java
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/SourceFactory.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/source/SourceFactory.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/source/SourceFactory.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/source/SourceFactory.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2002-2004 The Apache Software Foundation
+ * 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 org.apache.struts.flow.core.source;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.Map;
+
+/**
+ * A source factory creates new source objects.
+ * <p>
+ * Source factories are used to extend the source resolving mechanism
+ * with new URI schemes. A new source factory is added in order to
+ * handle a specific prototol. The {@link SourceResolver} delegates
+ * the handling of a URI containing this new scheme to the factory,
+ * and the factory can create a corresponding {@link Source} object.
+ *
+ * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
+ * @version $Id: SourceFactory.java,v 1.4 2004/02/28 11:47:26 cziegeler Exp $
+ */
+public interface SourceFactory {
+
+ /**
+ * Get a {@link Source} object.
+ * The factory creates a new {@link Source} object that can be used
+ * by the application. However, when this source object is not needed
+ * anymore it has to be released again using the {@link #release(Source)}
+ * method. This is achieved by using {@link SourceResolver#release(Source)} which
+ * finds the appropriate <code>SourceFactory</code>.
+ *
+ * @param location The URI to resolve - this URI includes the scheme.
+ * @param parameters additionnal named parameters (optionnal and can be <code>null</code>)
+ * that drive the creation of the <code>Source</code> object. Each implementation
+ * must specify what parameters it accepts.
+ * @return the created source object.
+ *
+ * @throws IOException if the source couldn't be created for some reason.
+ */
+ Source getSource( String location, Map parameters )
+ throws IOException, MalformedURLException;
+
+ /**
+ * Release a {@link Source} object.
+ *
+ * @param source the source to release.
+ */
+ void release( Source source );
+}
Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/SourceFactory.java
------------------------------------------------------------------------------
svn:executable = *
Added: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/SourceNotFoundException.java
URL: http://svn.apache.org/viewcvs/struts/flow/trunk/src/java/org/apache/struts/flow/core/source/SourceNotFoundException.java?rev=349187&view=auto
==============================================================================
--- struts/flow/trunk/src/java/org/apache/struts/flow/core/source/SourceNotFoundException.java (added)
+++ struts/flow/trunk/src/java/org/apache/struts/flow/core/source/SourceNotFoundException.java Sat Nov 26 23:10:08 2005
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2002-2004 The Apache Software Foundation
+ * 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 org.apache.struts.flow.core.source;
+
+/**
+ * This Exception should be thrown if the source could not be found.
+ *
+ * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
+ * @version CVS $Revision: 1.4 $ $Date: 2004/02/28 11:47:26 $
+ */
+public class SourceNotFoundException
+ extends SourceException
+{
+ /**
+ * Construct a new <code>SourceNotFoundException</code> instance.
+ *
+ * @param message The detail message for this exception.
+ */
+ public SourceNotFoundException( final String message )
+ {
+ super( message, null );
+ }
+
+ /**
+ * Construct a new <code>SourceNotFoundException</code> instance.
+ *
+ * @param message The detail message for this exception.
+ * @param throwable the root cause of the exception
+ */
+ public SourceNotFoundException( final String message, final Throwable throwable )
+ {
+ super( message, throwable );
+ }
+}
Propchange: struts/flow/trunk/src/java/org/apache/struts/flow/core/source/SourceNotFoundException.java
------------------------------------------------------------------------------
svn:executable = *
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org