cziegeler 02/04/17 01:43:59
Modified: src/java/org/apache/cocoon/transformation
AbstractSAXTransformer.java
Added: src/java/org/apache/cocoon/webapps/session
SessionConstants.java
src/java/org/apache/cocoon/webapps/session/acting
SessionAction.java
src/java/org/apache/cocoon/webapps/session/components
AbstractSessionComponent.java SessionManager.java
src/java/org/apache/cocoon/webapps/session/connector
Resource.java ResourceConnector.java
ResourceConnectorImpl.java URLRewriter.java
XMLLoader.java XMLSaver.java
src/java/org/apache/cocoon/webapps/session/context
RequestSessionContext.java
ResponseSessionContext.java SessionContext.java
SessionContextProvider.java
SimpleSessionContext.java
StandardSessionContextProvider.java
src/java/org/apache/cocoon/webapps/session/transformation
AbstractSessionTransformer.java
ConnectTransformer.java SessionPostTransformer.java
SessionPreTransformer.java SessionTransformer.java
src/java/org/apache/cocoon/webapps/session/xml
NodeListImpl.java XMLUtil.java
Log:
First part of 'sunShine' renamed to fit better in our packaging structure
Revision Changes Path
1.3 +9 -9
xml-cocoon2/src/java/org/apache/cocoon/transformation/AbstractSAXTransformer.java
Index: AbstractSAXTransformer.java
===================================================================
RCS file:
/home/cvs/xml-cocoon2/src/java/org/apache/cocoon/transformation/AbstractSAXTransformer.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- AbstractSAXTransformer.java 5 Apr 2002 10:59:12 -0000 1.2
+++ AbstractSAXTransformer.java 17 Apr 2002 08:43:54 -0000 1.3
@@ -98,7 +98,7 @@
* <li>Process the information</li>
* <li>Create new events from the processed information</li>
* </ul><p>
- * For all these four purposes the AbstractSunshineTransformer offers some
+ * For all these four purposes the AbstractSAXTransformer offers some
* powerful methods and hooks:
* <p>
* Namespace handling<p>
@@ -124,7 +124,7 @@
*
*
* @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
- * @version CVS $Id: AbstractSAXTransformer.java,v 1.2 2002/04/05 10:59:12
cziegeler Exp $
+ * @version CVS $Id: AbstractSAXTransformer.java,v 1.3 2002/04/17 08:43:54
cziegeler Exp $
*/
public abstract class AbstractSAXTransformer
extends AbstractTransformer
@@ -324,8 +324,8 @@
// this is our namespace:
try {
this.startTransformingElement(uri, name, raw, attr);
- } catch (ProcessingException sunShineException) {
- throw new SAXException("ProcessingException: " +
sunShineException, sunShineException);
+ } catch (ProcessingException pException) {
+ throw new SAXException("ProcessingException: " + pException,
pException);
} catch (IOException ioe) {
throw new SAXException("Exception occured during processing:
" + ioe, ioe);
}
@@ -349,9 +349,9 @@
// this is our namespace:
try {
this.endTransformingElement(uri, name, raw);
- } catch (ProcessingException sunShineException) {
- throw new SAXException("ProcessingException: " +
sunShineException,
- sunShineException);
+ } catch (ProcessingException pException) {
+ throw new SAXException("ProcessingException: " + pException,
+ pException);
} catch (IOException ioe) {
throw new SAXException("Exception occured during processing:
" + ioe, ioe);
}
@@ -441,7 +441,7 @@
DOMBuilder builder = new DOMBuilder();
this.addRecorder(builder);
builder.startDocument();
- builder.startElement("", "sunShine", "sunShine", new
AttributesImpl());
+ builder.startElement("", "cocoon", "cocoon", new AttributesImpl());
this.sendStartPrefixMapping();
@@ -464,7 +464,7 @@
this.sendEndPrefixMapping();
DOMBuilder builder = (DOMBuilder)this.removeRecorder();
- builder.endElement("", "sunShine", "sunShine");
+ builder.endElement("", "cocoon", "cocoon");
builder.endDocument();
// Create Document Fragment
1.1
xml-cocoon2/src/java/org/apache/cocoon/webapps/session/SessionConstants.java
Index: SessionConstants.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
[EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache
Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.cocoon.webapps.session;
/**
* The <code>Constants</code> used throughout the core of the session
management.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
* @version CVS $Id: SessionConstants.java,v 1.1 2002/04/17 08:43:54
cziegeler Exp $
*/
public interface SessionConstants {
/** The namespace used by the session transformers */
String SESSION_NAMESPACE_URI = "http://cocoon.apache.org/session/1.0";
/** Reserved Context: Request context */
String REQUEST_CONTEXT = "request";
/** Reserved Context: Response context */
String RESPONSE_CONTEXT= "response";
/** Reserved Context: Temp */
String TEMPORARY_CONTEXT = "temp";
/** The request parameter name for the form handling */
String SESSION_FORM_PARAMETER = "sessionform";
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/webapps/session/acting/SessionAction.java
Index: SessionAction.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
[EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache
Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.cocoon.webapps.session.acting;
import java.util.Map;
import org.apache.avalon.framework.component.ComponentException;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.thread.ThreadSafe;
import org.apache.cocoon.acting.ComposerAction;
import org.apache.cocoon.Constants;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.environment.Redirector;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.cocoon.webapps.session.components.SessionManager;
/**
* This action creates and terminates a session.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
* @version CVS $Id: SessionAction.java,v 1.1 2002/04/17 08:43:54 cziegeler
Exp $
*/
public final class SessionAction
extends ComposerAction
implements ThreadSafe {
public Map act(Redirector redirector,
SourceResolver resolver,
Map objectModel,
String source,
Parameters par)
throws ProcessingException {
SessionManager sessionManager = null;
try {
sessionManager =
(SessionManager)this.manager.lookup(SessionManager.ROLE);
final String action = par.getParameter("action", "create");
if ( action.equals("create") == true ) {
sessionManager.createSession();
} else if ( action.equals("terminate") == true ) {
final String mode = par.getParameter("mode", "immediately");
if ( mode.equals("immediately") == true) {
sessionManager.terminateSession(true);
} else if ( mode.equals("if-unused") == true ) {
sessionManager.terminateSession(false);
} else {
throw new ProcessingException("Unknown mode " + mode + "
for action " + action);
}
} else {
throw new ProcessingException("Unknown action: " + action);
}
} catch (ComponentException ce) {
throw new ProcessingException("Error during lookup of
sessionManager component.", ce);
} finally {
this.manager.release( sessionManager );
}
return EMPTY_MAP;
}
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/webapps/session/components/AbstractSessionComponent.java
Index: AbstractSessionComponent.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
[EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache
Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.cocoon.webapps.session.components;
import org.apache.avalon.excalibur.pool.Recyclable;
import org.apache.avalon.excalibur.source.SourceParameters;
import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.component.ComponentException;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.component.Composable;
import org.apache.avalon.framework.component.Recomposable;
import org.apache.avalon.framework.logger.AbstractLoggable;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.ResourceNotFoundException;
import org.apache.cocoon.components.RequestLifecycleComponent;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.Response;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.cocoon.webapps.session.components.SessionManager;
import org.apache.cocoon.webapps.session.connector.ResourceConnector;
import org.w3c.dom.DocumentFragment;
import org.xml.sax.SAXException;
import java.io.IOException;
import java.util.Map;
/**
* The base class for all components
*
* @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
* @version CVS $Id: AbstractSessionComponent.java,v 1.1 2002/04/17 08:43:55
cziegeler Exp $
*/
public abstract class AbstractSessionComponent
extends AbstractLoggable
implements Component, Composable, Recomposable, Recyclable,
RequestLifecycleComponent {
private SessionManager sessionManager;
private ResourceConnector resourceConnectorComponent;
protected ComponentManager manager;
/** The current object model */
protected Map objectModel;
/** The current source resolver */
protected SourceResolver resolver;
protected Request request;
protected Response response;
/**
* Composer interface. Get the Avalon ComponentManager.
*/
public void compose(ComponentManager manager) {
this.manager = manager;
}
/**
* Recomposable
*/
public void recompose( ComponentManager componentManager )
throws ComponentException {
this.recycle();
this.manager = componentManager;
}
/**
* Set the <code>SourceResolver</code>, objectModel <code>Map</code>,
* used to process the request.
* Set up the SessionManager component.
* This method is automatically called for each request. Do not invoke
* this method by hand.
*/
public void setup(SourceResolver resolver, Map objectModel)
throws ProcessingException, SAXException, IOException {
this.objectModel = objectModel;
this.resolver = resolver;
this.request = ObjectModelHelper.getRequest(objectModel);
this.response = ObjectModelHelper.getResponse(objectModel);
}
/**
* Get the SessionManager component
*/
protected SessionManager getSessionManager()
throws ProcessingException {
if (this.sessionManager == null) {
try {
this.sessionManager =
(SessionManager)this.manager.lookup(SessionManager.ROLE);
} catch (ComponentException ce) {
throw new ProcessingException("Error during lookup of
SessionManager component.", ce);
}
}
return this.sessionManager;
}
/**
* Get the resource connector
*/
protected ResourceConnector getResourceConnector()
throws ProcessingException {
if (this.resourceConnectorComponent == null) {
try {
this.resourceConnectorComponent =
(ResourceConnector)this.manager.lookup(ResourceConnector.ROLE);
} catch (ComponentException ce) {
throw new ProcessingException("Error during lookup of
resource connector.", ce);
}
}
return this.resourceConnectorComponent;
}
/**
* Recycle
*/
public void recycle() {
if (this.manager != null) {
this.manager.release(this.sessionManager);
this.manager.release(this.resourceConnectorComponent);
}
this.sessionManager = null;
this.resourceConnectorComponent = null;
this.objectModel = null;
this.resolver = null;
this.request = null;
this.response = null;
}
/**
* Load a resource.
* The resource connector usually throws a ResourceNotFound exception
* when a pipeline is not found. This exception is catched here
* and rethrown as a usual ProcessingException with the given message!
*/
public DocumentFragment loadXML(int resourceType,
Parameters typeParameters,
String resourceIdentifier,
SourceParameters resourceParameters,
String errorMessage)
throws ProcessingException {
try {
return this.getResourceConnector().loadXML(resourceType,
typeParameters,
resourceIdentifier,
resourceParameters);
} catch (ResourceNotFoundException rnfe) {
throw new ProcessingException(errorMessage, rnfe);
}
}
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/webapps/session/components/SessionManager.java
Index: SessionManager.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
[EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache
Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.cocoon.webapps.session.components;
import java.io.*;
import java.util.*;
import java.util.jar.*;
import org.apache.avalon.framework.component.Composable;
import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.component.ComponentException;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.component.Recomposable;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.logger.AbstractLoggable;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.excalibur.pool.Recyclable;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.components.RequestLifecycleComponent;
import org.apache.cocoon.environment.Environment;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.Response;
import org.apache.cocoon.environment.Session;
import org.apache.cocoon.environment.Source;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.cocoon.webapps.session.SessionConstants;
import org.apache.cocoon.webapps.session.context.*;
import org.apache.cocoon.webapps.session.connector.*;
import org.apache.cocoon.xml.XMLConsumer;
import org.apache.cocoon.xml.XMLUtils;
import org.apache.cocoon.xml.dom.DOMUtil;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.SAXException;
/**
* This is the basic session component.
*
* The main purpose of this component is session handling, maintaining
contexts
* and providing system management functions.
* The session information is divided into session contexts.
*
* Transaction management<p>
* </p>
* Transactions are a series of get/set calls to a sessuib context which must
* be seen as atomic (single modification).
* We distingish between reading and writing. Usually parallel reading is
* allowed but if one thread wants to write, no other can read or write.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
* @version CVS $Id: SessionManager.java,v 1.1 2002/04/17 08:43:55 cziegeler
Exp $
*/
public final class SessionManager
extends AbstractLoggable
implements Composable, Component, Recomposable, Recyclable,
RequestLifecycleComponent {
/** Avalon role */
public static final String ROLE = SessionManager.class.getName();;
/** This session attribute is used to store the information for the
inputxml tags */
private static final String ATTRIBUTE_INPUTXML_STORAGE=
"org.apache.cocoon.webapps.session.InputXMLStorage";
/** The <code>ComponentManager</code> */
private ComponentManager manager;
/** The request */
private Request request;
/** The response */
private Response response;
/** The object model */
private Map objectModel;
/** The resolver */
private SourceResolver resolver;
/** SessionContexts */
private Map contexts;
/** TransactionStates of the session contexts */
private Map transactionStates;
/** Session contexts delivered by a provider */
private Map deliveredContexts;
/** Registered context provider */
private static Map contextProvider = new HashMap();
/* The list of reserved contexts */
static private String[] reservedContextNames = {"session",
"context"};
/** Init the class,
* add the provider for the temp context
*/
static {
// add the provider for the sunSpot context
SessionContextProvider provider = new
StandardSessionContextProvider();
try {
SessionManager.addSessionContextProvider(provider,
SessionConstants.TEMPORARY_CONTEXT);
SessionManager.addSessionContextProvider(provider,
SessionConstants.REQUEST_CONTEXT);
SessionManager.addSessionContextProvider(provider,
SessionConstants.RESPONSE_CONTEXT);
} catch (ProcessingException local) {
throw new RuntimeException("Unable to register provider for
standard contexts.");
}
}
/**
* Avalon Composer Interface
*/
public void compose(ComponentManager manager) {
this.manager = manager;
}
/**
* Recomposable
*/
public void recompose( ComponentManager componentManager )
throws ComponentException {
this.manager = componentManager;
}
/**
* Set the <code>SourceResolver</code>, objectModel <code>Map</code>,
* used to process the request.
* Set up the SessionManager.
* This method is automatically called for each request. Do not invoke
* this method by hand.
*/
public void setup(SourceResolver resolver, Map objectModel)
throws ProcessingException, SAXException, IOException {
// no sync required
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN setup objectModel=" + objectModel);
}
this.objectModel = objectModel;
this.request = ObjectModelHelper.getRequest(objectModel);
this.response = ObjectModelHelper.getResponse(objectModel);
this.resolver = resolver;
this.processInputFields();
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END setup");
}
}
/**
* Recycling the SessionManager.
* This method is automatically called after each request. Do not invoke
* this method by hand.
*/
public void recycle() {
this.objectModel = null;
this.request = null;
this.response = null;
this.contexts = null;
if (this.deliveredContexts != null) {
this.deliveredContexts.clear();
}
this.transactionStates = null;
this.resolver = null;
}
/**
* Get the list of contexts
*/
protected Map getSessionContexts() {
if (this.contexts == null) {
Session session = this.getSession(true);
this.contexts =
(Map)session.getAttribute("org.apache.cocoon.webapps.session.context.SessionContext");
if (this.contexts == null) {
this.contexts = new HashMap(5, 3);
session.setAttribute("org.apache.cocoon.webapps.session.context.SessionContext",
this.contexts);
}
}
return this.contexts;
}
/**
* Get the list of contexts
*/
protected Map getSessionContextsTransactionStates() {
if (this.transactionStates == null) {
Session session = this.getSession(true);
this.transactionStates =
(Map)session.getAttribute("org.apache.cocoon.webapps.session.context.TransactionState");
if (this.transactionStates == null) {
this.transactionStates = new HashMap(5, 3);
session.setAttribute("org.apache.cocoon.webapps.session.context.TransactionState",
this.transactionStates);
}
}
return this.transactionStates;
}
/**
* Checks if the context name is a reserved context.
*/
static boolean isReservedContextName(String name) {
// synchronized (not needed)
int i, l;
boolean found;
found = false;
i = 0;
l = reservedContextNames.length;
while (i < l && found == false) {
found = reservedContextNames[i].equals(name);
i++;
}
if (found == false) {
found = (contextProvider.get(name) != null);
}
return found;
}
/**
* Add a context provider.
*/
public static synchronized void
addSessionContextProvider(SessionContextProvider provider,
String
contextName)
throws ProcessingException {
if (contextName != null && provider != null) {
if (isReservedContextName(contextName) == true) {
throw new ProcessingException("Unable to register context
'"+contextName+"' : Already registered.");
}
contextProvider.put(contextName, provider);
} else {
throw new ProcessingException("Unable to add new provider: Name
or provider info missing.");
}
}
/**
* Get a reserved context
*/
protected boolean existsReservedContext(String name) {
// synchronized (not needed)
SessionContext context = null;
SessionContextProvider provider =
(SessionContextProvider)contextProvider.get(name);
if (provider != null) {
if ( null != this.deliveredContexts ) {
context = (SessionContext)this.deliveredContexts.get(name);
}
}
return (context != null);
}
/**
* Get a reserved context
*/
protected SessionContext getReservedContext(String name)
throws ProcessingException {
// synchronized (not needed)
SessionContext context = null;
SessionContextProvider provider =
(SessionContextProvider)contextProvider.get(name);
if (provider != null) {
if ( null != this.deliveredContexts ) {
context = (SessionContext)this.deliveredContexts.get(name);
}
if (context == null) {
if ( null == this.deliveredContexts ) {
this.deliveredContexts = new HashMap(5);
}
context = provider.getSessionContext(name,
this.objectModel,
this.resolver,
this.manager);
if (context != null) this.deliveredContexts.put(name,
context);
}
}
return context;
}
/**
* Create a new session for the user.
* A new session is created for this user. If the user has already a
session,
* no new session is created and the old one is returned.
*/
public Session createSession() {
// synchronized
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN createSession");
}
Session session = this.getSession(true);
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END createSession session=" + session);
}
return session;
}
/**
* Get the session for the current user.
* If the user has no session right now, <CODE>null</CODE> is returned.
* If createFlag is true, the session is created if it does not exist.
*/
public Session getSession(boolean createFlag) {
// synchronized
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN getSession create=" + createFlag);
}
Session session = this.request.getSession(createFlag);
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END getSession session=" + session);
}
return session;
}
/**
* Terminate the current session.
* If the user has a session, this session is terminated and all of its
* data is deleted.
* @parameter force If this is set to true the session is terminated, if
* it is set to false, the session is only terminated
* if now session context is available.
*/
public void terminateSession(boolean force) {
// synchronized
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN terminateSession force="+force);
}
Session session = request.getSession(false);
if (session != null) {
if (force == true
|| this.hasSessionContext() == false) {
synchronized(session) {
session.invalidate();
}
}
}
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END terminateSession");
}
}
/**
* Create a new public context in the session.
* Create a new public session context for this user. If this context
* already exists no new context is created and the old one will be used
* instead.
*/
public SessionContext createContext(String name, String loadURI, String
saveURI)
throws IOException, SAXException, ProcessingException {
// synchronized
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN createContext name=" + name +
"load=" + loadURI +
"save=" + saveURI);
}
// test arguments
Session session = this.getSession(false);
if (session == null) {
throw new IllegalArgumentException("CreateContext: Session is
required");
}
if (name == null) {
throw new IllegalArgumentException("CreateContext: Name is
required");
}
SessionContext context;
synchronized(session) {
// test for reserved context
if (SessionManager.isReservedContextName(name) == true) {
throw new ProcessingException("SessionContext with name " +
name + " is reserved and cannot be created manually.");
}
Map contexts = this.getSessionContexts();
if (this.existsContext(name) == true) {
context = this.getContext(name);
} else {
context = new SimpleSessionContext();
Resource loadResource = (loadURI == null) ? null : new
Resource(this.resolver, loadURI);
Resource saveResource = (saveURI == null) ? null : new
Resource(this.resolver, saveURI);
context.setup(name, loadResource, saveResource);
contexts.put(name, context);
this.getSessionContextsTransactionStates().put(context, new
TransactionState());
}
}
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END createContext context="+context);
}
return context;
}
/**
* Delete a public context in the session.
* If the context exists for this user, it and all of its information
* is deleted.
*/
public void deleteContext(String name)
throws ProcessingException {
// synchronized
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN deleteContext name=" + name);
}
// test arguments
if (name == null) {
throw new IllegalArgumentException("SessionManager.deleteContext:
Name is required");
}
if (SessionManager.isReservedContextName(name) == true) {
throw new ProcessingException("SessionContext with name " + name
+ " is reserved and cannot be deleted manually.");
}
Session session = this.getSession(false);
if (session == null) {
throw new IllegalArgumentException("SessionManager.deleteContext:
Session is required");
}
synchronized(session) {
final Map contexts = this.getSessionContexts();
if (contexts.containsKey(name) == true) {
SessionContext context = (SessionContext)contexts.get(name);
contexts.remove(name);
this.getSessionContextsTransactionStates().remove(context);
}
}
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END deleteContext");
}
}
/**
* Get information from the context.
* A document fragment containg the xml data stored in the session context
* with the given name is returned. If the information is not available,
* <CODE>null</CODE> is returned.
* @param contextName The name of the public context.
* @param path XPath expression specifying which data to get.
* @return A DocumentFragment containing the data or <CODE>null</CODE>
*/
public DocumentFragment getContextFragment(String contextName,
String path)
throws ProcessingException {
// synchronized via context
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN getContextFragment name=" +
contextName + ", path=" + path);
}
// test arguments
if (contextName == null) {
throw new
IllegalArgumentException("SessionManager.getContextFragment: Name is required");
}
if (path == null) {
throw new
IllegalArgumentException("SessionManager.getContextFragment: Path is required");
}
SessionContext context;
if (SessionManager.isReservedContextName(contextName) == true) {
context = this.getReservedContext(contextName);
} else {
Session session = this.getSession(false);
if (session == null) {
throw new
IllegalArgumentException("SessionManager.getContextFragment: Session is
required for context " + contextName);
}
context = this.getContext(contextName);
}
if (context == null) {
throw new
IllegalArgumentException("SessionManager.getContextFragment: Context " +
contextName + "not found.");
}
DocumentFragment frag;
frag = context.getXML(path);
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END getContextFragment documentFragment="
+ (frag == null ? "null" : XMLUtils.serializeNodeToXML(frag)));
}
return frag;
}
/**
* Stream public context data.
* The document fragment containing the data from a path in the
* given context is streamed to the consumer.
*
* @param contextName The name of the public context.
* @param path XPath expression specifying which data to get.
*
* @return If the data is available <code>true</code> is returned,
* otherwise <code>false</code> is returned.
*/
public boolean streamContextFragment(String contextName,
String path,
XMLConsumer consumer)
throws SAXException, ProcessingException {
// synchronized via context
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN streamContextFragment name=" +
contextName + ", path=" + path + ", consumer"+consumer);
}
boolean streamed = false;
// test arguments
if (contextName == null) {
throw new
IllegalArgumentException("SessionManager.streamContextFragment: Name is
required");
}
if (path == null) {
throw new
IllegalArgumentException("SessionManager.streamContextFragment: Path is
required");
}
SessionContext context = this.getContext(contextName);
if (context == null) {
throw new
IllegalArgumentException("SessionManager.streamContextFragment: Context " +
contextName + "not found.");
}
streamed = context.streamXML(path, consumer, consumer);
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END streamContextFragment streamed=" +
streamed);
}
return streamed;
}
/**
* Set data in a public context.
* The document fragment containing the data is set at the given path in
the
* public session context.
*
* @param contextName The name of the public context.
* @param path XPath expression specifying where to set the data.
* @param fragment The DocumentFragment containing the data.
*
*/
public void setContextFragment(String contextName,
String path,
DocumentFragment fragment)
throws ProcessingException {
// synchronized via context
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN setContextFragment name=" +
contextName + ", path=" + path +
", fragment=" + (fragment == null ? "null" :
XMLUtils.serializeNodeToXML(fragment)));
}
// test arguments
if (contextName == null) {
throw new
IllegalArgumentException("SessionManager.setContextFragment: Name is required");
}
if (path == null) {
throw new
IllegalArgumentException("SessionManager.setContextFragment: Path is required");
}
if (fragment == null) {
throw new
IllegalArgumentException("SessionManager.setContextFragment: Fragment is
required");
}
// get context
SessionContext context = this.getContext(contextName);
// check context
if (context == null) {
throw new
IllegalArgumentException("SessionManager.setContextFragment: Context " +
contextName + "not found.");
}
context.setXML(path, fragment);
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END setContextFragment");
}
}
/**
* Append data in a public context.
* The document fragment containing the data is appended at the given
* path in the public session context.
*
* @param contextName The name of the public context.
* @param path XPath expression specifying where to append the
data.
* @param fragment The DocumentFragment containing the data.
*
*/
public void appendContextFragment(String contextName,
String path,
DocumentFragment fragment)
throws ProcessingException {
// synchronized via context
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN appendContextFragment name=" +
contextName +
", path=" + path +
", fragment=" + (fragment == null ? "null" :
XMLUtils.serializeNodeToXML(fragment)));
}
// test arguments
if (contextName == null) {
throw new
IllegalArgumentException("SessionManager.appendContextFragment: Name is
required");
}
if (path == null) {
throw new
IllegalArgumentException("SessionManager.appendContextFragment: Path is
required");
}
if (fragment == null) {
throw new
IllegalArgumentException("SessionManager.appendContextFragment: Fragment is
required");
}
// get context
SessionContext context = this.getContext(contextName);
// check context
if (context == null) {
throw new
IllegalArgumentException("SessionManager.appendContextFragment: Context " +
contextName + "not found.");
}
context.appendXML(path, fragment);
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END appendContextFragment");
}
}
/**
* Merge data in a public context.
* The document fragment containing the data is merged at the given
* path in the public session context.
*
* @param contextName The name of the public context.
* @param path XPath expression specifying where to merge the data.
* @param fragment The DocumentFragment containing the data.
*
*/
public void mergeContextFragment(String contextName,
String path,
DocumentFragment fragment)
throws ProcessingException {
// synchronized via context
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN mergeContextFragment name=" +
contextName + ", path=" + path +
", fragment=" + (fragment == null ? "null" :
XMLUtils.serializeNodeToXML(fragment)));
}
// test arguments
if (contextName == null) {
throw new
IllegalArgumentException("SessionManager.mergeContextFragment: Name is
required");
}
if (path == null) {
throw new
IllegalArgumentException("SessionManager.mergeContextFragment: Path is
required");
}
if (fragment == null) {
throw new
IllegalArgumentException("SessionManager.mergeContextFragment: Fragment is
required");
}
// get context
SessionContext context = this.getContext(contextName);
// check context
if (context == null) {
throw new
IllegalArgumentException("SessionManager.mergeContextFragment: Context " +
contextName + "not found.");
}
Node contextNode = context.getSingleNode(path);
if (contextNode == null) {
// no merge required
context.setXML(path, fragment);
} else {
this.importNode(contextNode, fragment, false);
context.setNode(path, contextNode);
}
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END mergeContextFragment");
}
}
/**
* Remove data in a public context.
* The data specified by the path is removed from the public session
context.
*
* @param contextName The name of the public context.
* @param path XPath expression specifying where to merge the data.
*
*/
public void removeContextFragment(String contextName,
String path)
throws ProcessingException {
// synchronized via context
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN removeContextFragment name=" +
contextName + ", path=" + path);
}
// test arguments
if (contextName == null) {
throw new
IllegalArgumentException("SessionManager.removeContextFragment: Name is
required");
}
if (path == null) {
throw new
IllegalArgumentException("SessionManager.removeContextFragment: Path is
required");
}
// get context
SessionContext context = this.getContext(contextName);
// check context
if (context == null) {
throw new
IllegalArgumentException("SessionManager.removeContextFragment: Context " +
contextName + "not found.");
}
context.removeXML(path);
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END removeContextFragment");
}
}
/**
* Import nodes. If preserve is set to true, the nodes
* marked with cocoon:preserve are always imported
* overwriting others!
*/
private void importNode(Node profile, Node delta, boolean preserve) {
// no sync req
NodeList profileChilds = null;
NodeList deltaChilds = delta.getChildNodes();
int i, len;
int m, l;
boolean found;
Node currentDelta = null;
Node currentProfile = null;
len = deltaChilds.getLength();
for(i = 0; i < len; i++) {
currentDelta = deltaChilds.item(i);
if (currentDelta.getNodeType() == Node.ELEMENT_NODE) {
// search the delta node in the profile
profileChilds = profile.getChildNodes();
l = profileChilds.getLength();
m = 0;
found = false;
while (found == false && m < l) {
currentProfile = profileChilds.item(m);
if (currentProfile.getNodeType() == Node.ELEMENT_NODE
&&
currentProfile.getNodeName().equals(currentDelta.getNodeName()) == true) {
// now we have found a node with the same name
// next: the attributes must match also
found =
DOMUtil.compareAttributes((Element)currentProfile, (Element)currentDelta);
}
if (found == false) m++;
}
if (found == true) {
// this is not new
if (preserve == true
&&
((Element)currentDelta).hasAttributeNS(SessionConstants.SESSION_NAMESPACE_URI,
"preserve")
&&
((Element)currentDelta).getAttributeNS(SessionConstants.SESSION_NAMESPACE_URI,
"preserve").equalsIgnoreCase("true")) {
// replace the original with the delta
profile.replaceChild(profile.getOwnerDocument().importNode(currentDelta, true),
currentProfile);
} else {
// do we have elements as children or text?
if (currentDelta.hasChildNodes() == true) {
currentDelta.normalize();
currentProfile.normalize();
// do a recursive call for sub elements
this.importNode((Element)currentProfile,
(Element)currentDelta, preserve);
// and now the text nodes: Remove all from the
profile and add all
// of the delta
NodeList childs = currentProfile.getChildNodes();
int index, max;
max = childs.getLength();
for(index = max - 1; index >= 0; index--) {
if (childs.item(index).getNodeType() ==
Node.TEXT_NODE) {
currentProfile.removeChild(childs.item(index));
}
}
childs = currentDelta.getChildNodes();
max = childs.getLength();
for(index = 0; index < max; index++) {
if (childs.item(index).getNodeType() ==
Node.TEXT_NODE) {
currentProfile.appendChild(currentProfile.getOwnerDocument()
.createTextNode(childs.item(index).getNodeValue()));
}
}
}
}
} else {
profile.appendChild(profile.getOwnerDocument().importNode(currentDelta, true));
}
}
}
}
/**
* Get the url for the request.
*/
public static String getURL(Request req) {
// no need for synchronized
boolean isDefaultPort = "http".equalsIgnoreCase(req.getScheme())
&& 80 == req.getServerPort();
return req.getScheme() + "://" +
req.getServerName() +
(isDefaultPort ? "" : ":" + req.getServerPort()) +
req.getContextPath() +
req.getServletPath() +
(req.getPathInfo() == null ? "" : req.getPathInfo());
}
/**
* Register input field and return the current value of the field.
* This is a private method and should not be invoked directly.
*/
public DocumentFragment registerInputField(String contextName,
String path,
String name,
String formName)
throws ProcessingException {
// synchronized
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN registerInputField
context="+contextName+", path="+path+", name="+name+", formName="+formName);
}
// test arguments
if (contextName == null) {
throw new
IllegalArgumentException("SessionManager.registerInputField: Context Name is
required");
}
if (path == null) {
throw new
IllegalArgumentException("SessionManager.registerInputField: Path is required");
}
if (name == null) {
throw new
IllegalArgumentException("SessionManager.registerInputField: Name is required");
}
if (formName == null) {
throw new
IllegalArgumentException("SessionManager.registerInputField: Form is required");
}
DocumentFragment value = null;
SessionContext context = this.getContext(contextName);
Session session = this.getSession(false);
if (session == null) {
throw new
IllegalArgumentException("SessionManager.registerInputField: Session is
required for context " + contextName);
}
synchronized(session) {
Map inputFields =
(Map)session.getAttribute(SessionManager.ATTRIBUTE_INPUTXML_STORAGE);
if (inputFields == null) {
inputFields = new HashMap(10);
session.setAttribute(SessionManager.ATTRIBUTE_INPUTXML_STORAGE, inputFields);
}
inputFields.put(name, new Object[] {context, path, formName});
value = context.getXML(path);
}
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END registerInputField value="+value);
}
return value;
}
/**
* Process all input fields.
* The fields are removed even if the request did not contain
* any values.
* This is a private method and should not be invoked directly.
*/
public void processInputFields()
throws ProcessingException {
// synchronized
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN processInputFields");
}
final String formName =
this.request.getParameter(SessionConstants.SESSION_FORM_PARAMETER);
if ( null != formName ) {
final Session session = this.getSession(false);
if (session != null) {
synchronized(session) {
final Map inputFields =
(Map)session.getAttribute(SessionManager.ATTRIBUTE_INPUTXML_STORAGE);
if (inputFields != null) {
final Enumeration keys =
this.request.getParameterNames();
String currentKey;
Object[] contextAndPath;
while (keys.hasMoreElements() == true) {
currentKey = (String)keys.nextElement();
if (inputFields.containsKey(currentKey) == true) {
contextAndPath =
(Object[])inputFields.get(currentKey);
inputFields.remove(currentKey);
SessionContext context =
(SessionContext)contextAndPath[0];
String path =
(String)contextAndPath[1];
if (formName.equals(contextAndPath[2]) ==
true) {
context.setXML(path,
this.getContextFragment(SessionConstants.REQUEST_CONTEXT,
"/parameter/"+currentKey));
}
}
}
}
// inputFields.clear();
}
}
}
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END processInputFields");
}
}
/**
* Get a public context.
* The session context with the given name is returned. If the context
does
* not exist <CODE>null</CODE> is returned.
*/
public synchronized SessionContext getContext(String name)
throws ProcessingException {
SessionContext context;
if (SessionManager.isReservedContextName(name) == true) {
context = this.getReservedContext(name);
} else {
Session session = this.getSession(false);
if (session == null) {
throw new
IllegalArgumentException("SessionManager.getContext: Session is required.");
}
synchronized (session) {
final Map contexts = this.getSessionContexts();
context = (SessionContext)contexts.get(name);
}
}
return context;
}
/**
* Check if a context exists
*/
public synchronized boolean hasSessionContext() {
Session session = this.getSession(false);
if (session == null) {
throw new
IllegalArgumentException("SessionManager.hasSessionContext: Session is
required.");
}
synchronized (session) {
final Map contexts = this.getSessionContexts();
return !(contexts.isEmpty());
}
}
/**
* Check if a public context exists.
* If the session context with the given name exists, <CODE>true</CODE>
is
* returned.
*/
public synchronized boolean existsContext(String name) {
Session session = this.getSession(false);
if (session == null) {
throw new IllegalArgumentException("SessionManager.existsContext:
Session is required.");
}
synchronized (session) {
final Map contexts = this.getSessionContexts();
boolean result = contexts.containsKey(name);
if (result == false && SessionManager.isReservedContextName(name)
== true) {
result = this.existsReservedContext(name);
}
return result;
}
}
private class TransactionState {
/** number readers reading*/
public int nr=0;
/** number of readers total (reading or waiting to read)*/
public int nrtotal=0;
/** number writers writing, 0 or 1 */
public int nw=0;
/** number of writers total (writing or waiting to write)*/
public int nwtotal=0;
}
/**
* Reset the transaction management state.
*/
public void resetTransactions(SessionContext context) {
TransactionState ts =
(TransactionState)this.getSessionContextsTransactionStates().get(context);
ts.nr=0;
ts.nrtotal=0;
ts.nw=0;
ts.nwtotal=0;
}
/**
* Start a reading transaction.
* This call must always be matched with a stopReadingTransaction().
* Otherwise the session context is blocked.
*/
public synchronized void startReadingTransaction(SessionContext context)
throws ProcessingException {
TransactionState ts =
(TransactionState)this.getSessionContextsTransactionStates().get(context);
ts.nrtotal++;
while (ts.nw!=0) {
try {
wait();
} catch (InterruptedException local) {
throw new ProcessingException("Interrupted", local);
}
}
ts.nr++;
}
/**
* Stop a reading transaction.
* This call must always be done for each startReadingTransaction().
* Otherwise the session context is blocked.
*/
public synchronized void stopReadingTransaction(SessionContext context) {
TransactionState ts =
(TransactionState)this.getSessionContextsTransactionStates().get(context);
ts.nr--;
ts.nrtotal--;
if (ts.nrtotal==0) notify();
}
/**
* Start a writing transaction.
* This call must always be matched with a stopWritingTransaction().
* Otherwise the session context is blocked.
*/
public synchronized void startWritingTransaction(SessionContext context)
throws ProcessingException {
TransactionState ts =
(TransactionState)this.getSessionContextsTransactionStates().get(context);
ts.nwtotal++;
while (ts.nrtotal+ts.nw != 0) {
try {
wait();
} catch (InterruptedException local) {
throw new ProcessingException("Interrupted", local);
}
}
ts.nw=1;
}
/**
* Stop a writing transaction.
* This call must always be done for each startWritingTransaction().
* Otherwise the session context is blocked.
*/
public synchronized void stopWritingTransaction(SessionContext context) {
TransactionState ts =
(TransactionState)this.getSessionContextsTransactionStates().get(context);
ts.nw=0;
ts.nwtotal--;
notifyAll();
}
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/webapps/session/connector/Resource.java
Index: Resource.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
[EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache
Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.cocoon.webapps.session.connector;
import java.io.IOException;
import java.io.Serializable;
import org.apache.avalon.excalibur.source.SourceParameters;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.environment.Source;
import org.apache.cocoon.environment.SourceResolver;
import org.xml.sax.SAXException;
/**
* This is a resource. It consists of a name and a type and possibly some
* parameters.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
* @version CVS $Id: Resource.java,v 1.1 2002/04/17 08:43:56 cziegeler Exp $
*/
public final class Resource
implements Serializable {
/** The resource type, e.g. file */
private int resourceType;
/** The resource identifier, e.g. file name */
private String resourceIdentifier;
/** The resource parameters (or null) */
private SourceParameters parameters;
/**
* Construct a new resource
*/
public Resource(SourceResolver resolver,
String identifier)
throws ProcessingException, SAXException, IOException {
if ( identifier.startsWith("class://") ) {
this.resourceType = ResourceConnector.RESOURCE_TYPE_CLASS;
this.resourceIdentifier =
identifier.substring("class://".length());
} else if ( identifier.indexOf(":/") == -1) {
// relative, resolve it first
Source source = null;
try {
source = resolver.resolve(identifier);
identifier = source.getSystemId();
if ( identifier.startsWith("file:") ) {
this.resourceType = ResourceConnector.RESOURCE_TYPE_FILE;
this.resourceIdentifier =
identifier.substring("file:".length());
} else {
this.resourceType = ResourceConnector.RESOURCE_TYPE_URI;
this.resourceIdentifier = identifier;
}
} finally {
source.recycle();
}
} else {
// check for relative cocoon:/ protocol
if (identifier.startsWith("cocoon:/")
&& identifier.charAt("cocoon:/".length()) != '/') {
// FIXME (CZ)
throw new ProcessingException("Relative cocoon: URIs
currently not supported.");
}
if ( identifier.startsWith("file:") ) {
this.resourceType = ResourceConnector.RESOURCE_TYPE_FILE;
this.resourceIdentifier =
identifier.substring("file:".length());
} else {
this.resourceType = ResourceConnector.RESOURCE_TYPE_URI;
this.resourceIdentifier = identifier;
}
}
}
/**
* Get the resource type
*/
public int getResourceType() {
return this.resourceType;
}
/**
* Get the resource identifier
*/
public String getResourceIdentifier() {
return this.resourceIdentifier;
}
/**
* Set some parameters
*/
public void setResourceParameters(SourceParameters pars) {
this.parameters = pars;
}
/**
* Get the parameters
*/
public SourceParameters getResourceParameters() {
return this.parameters;
}
/**
* PP for debugging
*/
public String toString() {
return Resource.class.getName() +
this.resourceIdentifier +
" (" + this.resourceType + ")";
}
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/webapps/session/connector/ResourceConnector.java
Index: ResourceConnector.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
[EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache
Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.cocoon.webapps.session.connector;
import java.io.IOException;
import org.w3c.dom.DocumentFragment;
import org.apache.avalon.excalibur.source.SourceParameters;
import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.ProcessingException;
import org.xml.sax.ContentHandler;
import org.xml.sax.ext.LexicalHandler;
/**
* The Component for loading and saving xml to external resources.
*
* An external resource is specified by a type and an identifier. The type
* gives the connection information (file, http etc) and the identifier
* identifies the resource itself (filename, http-address etc).
*
* @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
* @version CVS $Id: ResourceConnector.java,v 1.1 2002/04/17 08:43:56
cziegeler Exp $
*/
public interface ResourceConnector
extends Component {
/** Role name */
static public final String ROLE = ResourceConnector.class.getName();
/** No type information specified. */
static public final int RESOURCE_TYPE_NONE = 0;
/**
* Resource is an URI.
* The resource is specified by an uri, local or remote. If it is a
* remote resource the http protocol is used. For local resources the
* internal pipelines are invoked.
* The <code>typeParameter</code> "method" specifies the http method
(POST,
* GET etc) - standard is POST if parameters are used, without parameters
* it is GET.
* The <code>typeParameter</code> "followRedirects" specifies if the
* connection should follow redirects.
* URLRewriting can be turned on by specifying the parameters defined
* for the <code>URLRewriter</code>.
* If an URI is saved (e.g. saveXML) this is the same as loading from
* this URI and specifying a resource parameter named "content" with
* the document fragment as a string.
*/
static public final int RESOURCE_TYPE_URI = 1;
/**
* Resource is a class.
* The class must conform to the XMLLoader or the XMLSaver interface.
*/
static public final int RESOURCE_TYPE_CLASS = 2;
/**
* Resource is a file.
*/
static public final int RESOURCE_TYPE_FILE = 3;
/**
* Load an XML Fragment from a resource.
*
* @param resourceType The type of the connection.
* @param typeParameters Connection Parameters.
* @param resourceIdentifier The resource name (filename, http address
etc)
* @param resourceParameters Parameters for the resource.
*
* @return The loaded data.
*/
public DocumentFragment loadXML(int resourceType,
Parameters typeParameters,
String resourceIdentifier,
SourceParameters resourceParameters)
throws ProcessingException;
/**
* Save an XML Fragment to a resource.
*
* @param resourceType The type of the connection.
* @param typeParameters Connection Parameters.
* @param resourceIdentifier The resource name (filename, http address
etc)
* @param resourceParameters Parameters for the resource.
* @param fragment The data to be saved.
*/
public void saveXML(int resourceType,
Parameters typeParameters,
String resourceIdentifier,
SourceParameters resourceParameters,
DocumentFragment fragment)
throws ProcessingException;
/**
* Stream an XML resource.
* This is like loading the resource and then streaming it, but without
* the Resource->SAX->DOM->SAX transformation, its simply: Resource->SAX
* All SAX events are send except of the startDocument() and
* endDocument() event.
*
* @param resourceType The type of the connection.
* @param typeParameters Connection Parameters.
* @param resourceIdentifier The resource name (filename, http address
etc)
* @param resourceParameters Parameters for the resource.
* @param contentHandler The SAX ContentHandler receiving the events.
* @param lexicalHandler The SAX LexicalHandler receiving the events.
*/
public void streamXML(int resourceType,
Parameters typeParameters,
String resourceIdentifier,
SourceParameters resourceParameters,
ContentHandler contentHandler,
LexicalHandler lexicalHandler)
throws ProcessingException;
/**
* Get the content of a resource.
* This method can be used to get any data from a resource, not only xml.
* The data is represented by a String.
*
* @param resourceType The type of the connection.
* @param typeParameters Connection Parameters.
* @param resourceIdentifier The resource name (filename, http address
etc)
* @param resourceParameters Parameters for the resource.
*/
public String getContent(int resourceType,
Parameters typeParameters,
String resourceIdentifier,
SourceParameters resourceParameters)
throws ProcessingException;
/**
* Save a String to a resource.
*
* @param resourceType The type of the connection.
* @param typeParameters Connection Parameters.
* @param resourceIdentifier The resource name (filename, http address
etc)
* @param resourceParameters Parameters for the resource.
* @param content The data to be saved.
*/
public void saveContent(int resourceType,
Parameters typeParameters,
String resourceIdentifier,
SourceParameters resourceParameters,
String content)
throws ProcessingException;
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/webapps/session/connector/ResourceConnectorImpl.java
Index: ResourceConnectorImpl.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
[EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache
Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.cocoon.webapps.session.connector;
import java.io.*;
import java.net.*;
import java.util.*;
import org.apache.avalon.excalibur.pool.Recyclable;
import org.apache.avalon.excalibur.source.SourceParameters;
import org.apache.avalon.excalibur.source.SourceUtil;
import org.apache.avalon.framework.component.Composable;
import org.apache.avalon.framework.component.Component;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.component.ComponentException;
import org.apache.avalon.framework.component.ComponentSelector;
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.framework.logger.AbstractLoggable;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.Processor;
import org.apache.cocoon.ResourceNotFoundException;
import org.apache.cocoon.components.RequestLifecycleComponent;
import org.apache.cocoon.components.parser.Parser;
import org.apache.cocoon.components.source.URLSource;
import org.apache.cocoon.environment.Context;
import org.apache.cocoon.environment.Environment;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.Response;
import org.apache.cocoon.environment.Source;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.cocoon.webapps.session.xml.XMLUtil;
import org.apache.cocoon.xml.XMLConsumer;
import org.apache.cocoon.xml.dom.DOMBuilder;
import org.apache.cocoon.xml.IncludeXMLConsumer;
import org.apache.cocoon.xml.XMLUtils;
import org.w3c.dom.*;
import org.xml.sax.*;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.helpers.*;
/**
* The Component for loading and saving xml to external resource connectors.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
* @version CVS $Id: ResourceConnectorImpl.java,v 1.1 2002/04/17 08:43:56
cziegeler Exp $
*/
public final class ResourceConnectorImpl
extends AbstractLoggable
implements Recyclable, ResourceConnector,
Composable, RequestLifecycleComponent {
/** The <code>ComponentManager</code> */
protected ComponentManager manager;
/** Empty attributes */
protected Attributes emptyAttributes = new AttributesImpl();
protected Map objectModel;
protected SourceResolver resolver;
/**
* Composer
*/
public void compose(ComponentManager manager)
throws ComponentException {
this.manager = manager;
}
/**
* Set the <code>SourceResolver</code>, objectModel <code>Map</code>,
* used to process the request.
* This method is automatically called for each request. Do not invoke
* this method by hand.
*/
public void setup(SourceResolver resolver, Map objectModel)
throws ProcessingException, SAXException, IOException {
this.objectModel = objectModel;
this.resolver = resolver;
}
/**
* Recycle
*/
public void recycle() {
this.objectModel = null;
this.resolver = null;
}
private static String[] outputKeys = new String[] {
javax.xml.transform.OutputKeys.CDATA_SECTION_ELEMENTS,
javax.xml.transform.OutputKeys.DOCTYPE_PUBLIC,
javax.xml.transform.OutputKeys.DOCTYPE_SYSTEM,
javax.xml.transform.OutputKeys.ENCODING,
javax.xml.transform.OutputKeys.INDENT,
javax.xml.transform.OutputKeys.MEDIA_TYPE,
javax.xml.transform.OutputKeys.METHOD,
javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION,
javax.xml.transform.OutputKeys.STANDALONE,
javax.xml.transform.OutputKeys.VERSION};
/**
* Set OutputKeys from parameters
*/
private void setOutputKeys(Properties properties, Parameters parameters) {
if (properties != null && parameters != null) {
for(int i = 0; i < outputKeys.length; i++) {
final String value = parameters.getParameter(outputKeys[i],
null);
if (value != null) {
properties.setProperty(outputKeys[i], value);
}
}
}
}
/**
* Get a <code>Source</code> object
*/
private Source getSource(String uri,
Parameters typeParameters,
SourceParameters resourceParameters)
throws IOException, SAXException, ProcessingException {
Source input;
// Test: local uri (= same servlet/cocoon) ?
if (uri.startsWith("/") == true) {
// server-absolute url is transformed to absolute url
Request request = ObjectModelHelper.getRequest(objectModel);
uri = request.getScheme() + "://" +
request.getServerName() + ":" + request.getServerPort() +
uri;
}
// first step: encode parameters which are already appended to the url
int queryPos = uri.indexOf('?');
if (queryPos != -1) {
String queryString = uri.substring(queryPos+1);
SourceParameters queries = new SourceParameters(queryString);
if (queries.hasParameters()) {
StringBuffer buffer;
buffer = new StringBuffer(uri.substring(0, queryPos));
String current;
Iterator iter = queries.getParameterNames();
char separator = '?';
Iterator values;
while (iter.hasNext() == true) {
current = (String)iter.next();
values = queries.getParameterValues(current);
while (values.hasNext()) {
buffer.append(separator)
.append(current)
.append('=')
.append(SourceUtil.encode((String)values.next()));
separator = '&';
}
}
uri = buffer.toString();
}
}
boolean followRedirects = (typeParameters != null ?
typeParameters.getParameterAsBoolean("followRedirects", true)
: true);
String method = (typeParameters != null ?
typeParameters.getParameter("method", "GET")
: "GET");
if (method.equalsIgnoreCase("POST") == true
&& (resourceParameters == null ||
resourceParameters.hasParameters() == false)) {
method = "GET";
}
if ((method.equalsIgnoreCase("POST") == false
|| uri.startsWith("cocoon:") == true)
&& resourceParameters != null
&& resourceParameters.hasParameters()) {
int pos = uri.indexOf(";jsessionid=");
if (uri.startsWith("cocoon:") == false) {
if (pos != -1) uri = uri.substring(0, pos);
uri = SourceUtil.appendParameters(uri, resourceParameters);
} else {
StringBuffer buf;
if (pos == -1) {
buf = new StringBuffer(uri);
} else {
buf = new StringBuffer(uri.substring(0, pos));
}
buf.append((uri.indexOf('?') == -1 ? '?' : '&'));
buf.append(resourceParameters.getEncodedQueryString());
uri = buf.toString();
}
}
if (this.getLogger().isInfoEnabled() == true) {
this.getLogger().info("Getting content of '"+uri+"' using method
" + method);
}
input = this.resolver.resolve(uri);
if (method.equalsIgnoreCase("POST") == true
&& input instanceof URLSource) {
((URLSource)input).setPostParameters(resourceParameters);
}
if (followRedirects == false && input instanceof URLSource) {
((URLSource)input).setFollowRedirects(false);
}
return input;
}
/**
* Load XML
*/
private DocumentFragment loadXMLFromURI(Parameters typeParameters,
String uri,
SourceParameters
resourceParameters)
throws IOException, SAXException, ProcessingException {
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN loadXMLFromURI uri=" + uri +
", typeParams="+typeParameters+
", parameters="+resourceParameters);
}
if (uri == null || uri.trim().length() == 0) {
throw new IllegalArgumentException("loadXMLFromURI: URI is
required");
}
long startTime = System.currentTimeMillis();
DocumentFragment recordedDocFrag = null;
DOMBuilder builder;
builder = new DOMBuilder();
builder.startDocument();
builder.startElement("", "cocoon", "cocoon", this.emptyAttributes);
IncludeXMLConsumer filter;
// Test for url rewriting
if (typeParameters != null
&& typeParameters.getParameter(URLRewriter.PARAMETER_MODE, null)
!= null) {
XMLConsumer consumer = new URLRewriter(typeParameters,
builder,
builder);
filter = new IncludeXMLConsumer(consumer, consumer);
} else {
filter = new IncludeXMLConsumer(builder, builder);
}
Source input = null;
try {
input = this.getSource(uri, typeParameters, resourceParameters);
if (input != null) {
input.toSAX(filter);
}
} finally {
if (input != null) input.recycle();
input = null;
}
builder.endElement("", "cocoon", "cocoon");
builder.endDocument();
// Create Document Fragment
final Document doc = builder.getDocument();
recordedDocFrag = doc.createDocumentFragment();
final Node root = doc.getDocumentElement();
Node child;
while (root.hasChildNodes() == true) {
child = root.getFirstChild();
child.normalize();
root.removeChild(child);
recordedDocFrag.appendChild(child);
}
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END loadXMLFromURI
fragment="+(recordedDocFrag == null ? "null" :
XMLUtils.serializeNodeToXML(recordedDocFrag)));
}
return recordedDocFrag;
}
/**
* Save XML to an URI. The fragment is passed to the resource as the value
* of the parameter "content".
*/
private void saveXMLToURI(Parameters typeParameters,
String uri,
SourceParameters resourceParameters,
DocumentFragment fragment)
throws IOException, SAXException, ProcessingException {
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN saveXMLToURI fragment="+(fragment
== null ? "null" : XMLUtils.serializeNodeToXML(fragment))+
", typeParams="+typeParameters+
", uri=" + uri +
", parameters="+resourceParameters);
}
if (uri == null || uri.trim().length() == 0) {
throw new IllegalArgumentException("saveXMLToURI: URI is
required");
}
Properties format = XMLUtils.defaultSerializeToXMLFormat(true);
this.setOutputKeys(format, typeParameters);
String content = XMLUtils.serializeNode(fragment, format);
if (resourceParameters == null) {
resourceParameters = new SourceParameters();
} else {
resourceParameters = (SourceParameters)resourceParameters.clone();
}
resourceParameters.setSingleParameterValue("content", content);
// The trick here is that we do a simple loadXML and ignore the result
this.loadXMLFromURI(typeParameters, uri, resourceParameters);
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END saveXMLToURI");
}
}
/**
* Save XML to an URI. The fragment is passed to the resource as the value
* of the parameter "content".
*/
private void saveContentToURI(Parameters typeParameters,
String uri,
SourceParameters resourceParameters,
String content)
throws IOException, SAXException, ProcessingException {
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN saveContentToURI content="+content+
", typeParams="+typeParameters+
", uri=" + uri +
", parameters="+resourceParameters);
}
if (uri == null || uri.trim().length() == 0) {
throw new IllegalArgumentException("saveContentToURI: URI is
required");
}
if (resourceParameters == null) {
resourceParameters = new SourceParameters();
} else {
resourceParameters = (SourceParameters)resourceParameters.clone();
}
resourceParameters.setSingleParameterValue("content", content);
// The trick here is that we do a simple loadXML and ignore the result
this.loadXMLFromURI(typeParameters, uri, resourceParameters);
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END saveContentToURI");
}
}
/**
* Load XML by using an XMLLoader
*/
private DocumentFragment loadXMLFromClass(Parameters
typeParameters,
String className,
SourceParameters
resourceParameters)
throws ProcessingException {
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN loadXMLFromClass class=" +
className+
", typeParams="+typeParameters+
", parameters="+resourceParameters);
}
DocumentFragment frag;
try {
Class loaderClass = Class.forName(className);
XMLLoader loader = (XMLLoader)loaderClass.newInstance();
frag = loader.load(this.objectModel, resourceParameters);
} catch (ClassNotFoundException cnfException) {
throw new ProcessingException("loadXMLFromClass: Class not found:
" + className, cnfException);
} catch (IllegalAccessException iaException) {
throw new ProcessingException("loadXMLFromClass: Illegal Access:
" + className, iaException);
} catch (InstantiationException iException) {
throw new ProcessingException("loadXMLFromClass: Instantion
exception: " + className, iException);
}
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END loadXMLFromClass fragment="+(frag ==
null ? "null" : XMLUtils.serializeNodeToXML(frag)));
}
return frag;
}
/**
* Save XML by using an XMLSaver
*/
private void saveXMLToClass(Parameters typeParameters,
String className,
SourceParameters resourceParameters,
DocumentFragment fragment)
throws ProcessingException {
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN saveXMLToClass fragment="+(fragment
== null ? "null" : XMLUtils.serializeNodeToXML(fragment))+
", typeParams="+typeParameters+
", class=" + className+
", params="+resourceParameters);
}
try {
Class saverClass = Class.forName(className);
XMLSaver saver = (XMLSaver)saverClass.newInstance();
saver.save(fragment, this.objectModel, resourceParameters);
} catch (ClassNotFoundException cnfException) {
throw new ProcessingException("saveXMLToClass: Class not found: "
+ className, cnfException);
} catch (IllegalAccessException iaException) {
throw new ProcessingException("saveXMLToClass: Illegal Access: "
+ className, iaException);
} catch (InstantiationException iException) {
throw new ProcessingException("saveXMLToClass: Instantion
exception: " + className, iException);
}
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END saveXMLToClass");
}
}
/**
* Load XML from a file
*/
private DocumentFragment loadXMLFromFile(Parameters
typeParameters,
String fileName,
SourceParameters
resourceParameters)
throws ProcessingException, IOException, SAXException {
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN loadXMLFromFile fileName=" +
fileName+
", typeParams="+typeParameters+
", parameters="+resourceParameters);
}
DocumentFragment frag = null;
long startTime = System.currentTimeMillis();
Source input = null;
try {
input = this.resolver.resolve(fileName);
DOMBuilder builder = new DOMBuilder();
builder.startDocument();
builder.startElement("", "cocoon", "cocoon",
this.emptyAttributes);
IncludeXMLConsumer filter = new IncludeXMLConsumer(builder,
builder);
input.toSAX(filter);
builder.endElement("", "cocoon", "cocoon");
builder.endDocument();
// Create Document Fragment
final Document doc = builder.getDocument();
frag = doc.createDocumentFragment();
final Node root = doc.getDocumentElement();
Node child;
while (root.hasChildNodes() == true) {
child = root.getFirstChild();
child.normalize();
root.removeChild(child);
frag.appendChild(child);
}
} finally {
if (input != null) input.recycle();
input = null;
}
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END loadXMLFromFile fragment="+(frag ==
null ? "null" : XMLUtils.serializeNodeToXML(frag)));
}
return frag;
}
/**
* Save XML to a file
*/
private void saveXMLToFile(Parameters typeParameters,
String fileName,
SourceParameters resourceParameters,
DocumentFragment fragment)
throws SAXException, IOException, ProcessingException {
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN saveXMLToFile fragment="+(fragment
== null ? "null" : XMLUtils.serializeNodeToXML(fragment))+
", typeParams="+typeParameters+
", file=" + fileName +
", params="+resourceParameters);
}
try {
// cleanup fragment
NodeList childs = fragment.getChildNodes();
if (childs != null) {
Node[] list = new Node[childs.getLength()];
for(int i = 0; i < childs.getLength(); i++) {
list[i] = childs.item(i);
}
for(int i = 0; i < list.length; i++) {
if (list[i].getNodeType() == Node.TEXT_NODE) {
String value = list[i].getNodeValue();
if (value == null
|| value.length() == 0
|| value.trim().length() == 0) {
list[i].getParentNode().removeChild(list[i]);
}
}
}
}
Source input = null;
try {
Properties format =
XMLUtils.defaultSerializeToXMLFormat(false);
this.setOutputKeys(format, typeParameters);
input = this.resolver.resolve(fileName);
String absolutePath = input.getSystemId();
if (absolutePath.startsWith("file:") == false) {
throw new ProcessingException("Saving to " + fileName + "
is not possible.");
}
File file = new
File(absolutePath.substring("file:".length()));
if (file.exists() == false) {
File directory = file.getParentFile();
if (directory.exists() == false) {
directory.mkdirs();
}
file.createNewFile();
}
String xml = XMLUtils.serializeNode(fragment, format);
Writer writer = new BufferedWriter(new FileWriter(file));;
writer.write(xml);
writer.flush();
writer.close();
writer = null;
} finally {
if (input != null) input.recycle();
input = null;
}
} catch (IOException ioe) {
throw new ProcessingException("saveXMLToFile: IOException: " +
ioe, ioe);
}
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END saveXMLToFile");
}
}
/**
* Save XML to a file
*/
private void saveContentToFile(Parameters typeParameters,
String fileName,
SourceParameters resourceParameters,
String content)
throws SAXException, IOException, ProcessingException {
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN saveContentToFile content="+content+
", typeParams="+typeParameters+
", file=" + fileName +
", params="+resourceParameters);
}
try {
Source input = null;
try {
input = this.resolver.resolve(fileName);
String absolutePath = input.getSystemId();
if (absolutePath.startsWith("file:") == false) {
throw new ProcessingException("Saving to " + fileName + "
is not possible.");
}
File file = new
File(absolutePath.substring("file:".length()));
if (file.exists() == false) {
File directory = file.getParentFile();
if (directory.exists() == false) {
directory.mkdirs();
}
file.createNewFile();
}
Writer writer = new BufferedWriter(new FileWriter(file));
writer.write(content);
writer.flush();
writer.close();
writer = null;
} finally {
if (input != null) input.recycle();
input = null;
}
} catch (IOException ioe) {
throw new ProcessingException("saveContentToFile: IOException: "
+ ioe, ioe);
}
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END saveContentToFile");
}
}
/**
* Load an XML Fragment from a resource
*/
public DocumentFragment loadXML(int resourceType,
Parameters typeParameters,
String resourceIdentifier,
SourceParameters resourceParameters)
throws ProcessingException {
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("start loading '"+resourceIdentifier+"'");
}
DocumentFragment frag = null;
try {
switch (resourceType) {
case ResourceConnector.RESOURCE_TYPE_URI: frag =
this.loadXMLFromURI(typeParameters,
resourceIdentifier, resourceParameters);
break;
case ResourceConnector.RESOURCE_TYPE_CLASS: frag =
this.loadXMLFromClass(typeParameters,
resourceIdentifier, resourceParameters);
break;
case ResourceConnector.RESOURCE_TYPE_FILE: frag =
this.loadXMLFromFile(typeParameters,
resourceIdentifier, resourceParameters);
break;
default: throw new ProcessingException("ResourceConnector:
type " +
resourceType + " not supported.");
}
} catch (SAXException ioe) {
throw new ProcessingException("SAXException: " + ioe, ioe);
} catch (IOException ioe) {
throw new ProcessingException("IOException: " + ioe, ioe);
}
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("finished loading
'"+resourceIdentifier+"'");
}
return frag;
}
/**
* Save an XML Fragment to a resource
*/
public void saveXML(int resourceType,
Parameters typeParameters,
String resourceIdentifier,
SourceParameters resourceParameters,
DocumentFragment fragment)
throws ProcessingException {
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("start saving '"+resourceIdentifier+"'");
}
try {
switch (resourceType) {
case ResourceConnector.RESOURCE_TYPE_URI:
this.saveXMLToURI(typeParameters,
resourceIdentifier, resourceParameters, fragment);
break;
case ResourceConnector.RESOURCE_TYPE_CLASS:
this.saveXMLToClass(typeParameters,
resourceIdentifier, resourceParameters, fragment);
break;
case ResourceConnector.RESOURCE_TYPE_FILE:
this.saveXMLToFile(typeParameters,
resourceIdentifier, resourceParameters, fragment);
break;
default: throw new ProcessingException("ResourceConnector:
type " +
resourceType + " not supported.");
}
} catch (SAXException ioe) {
throw new ProcessingException("SAXException: " + ioe, ioe);
} catch (IOException ioe) {
throw new ProcessingException("IOException: " + ioe, ioe);
}
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("finished saving
'"+resourceIdentifier+"'");
}
}
/**
* Stream XML from a file
*/
private void streamXMLFromFile(Parameters typeParameters,
String fileName,
SourceParameters resourceParameters,
org.xml.sax.ContentHandler contentHandler,
LexicalHandler lexicalHandler)
throws ProcessingException {
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN streamXMLFromFile fileName=" +
fileName +
", typeParams="+typeParameters+
", parameters="+resourceParameters);
}
long startTime = System.currentTimeMillis();
Source input = null;
try {
input = this.resolver.resolve(fileName);
IncludeXMLConsumer filter = new
IncludeXMLConsumer(contentHandler, lexicalHandler);
input.toSAX(filter);
} catch (SAXException sax) {
throw new ProcessingException("SAXException: " + sax, sax);
} catch (IOException ioe) {
throw new ProcessingException("IOException: " + ioe, ioe);
} finally {
if (input != null) input.recycle();
input = null;
}
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END streamXMLFromFile");
}
}
/**
* Stream XML
*/
private void streamXMLFromURI(Parameters typeParameters,
String uri,
SourceParameters resourceParameters,
org.xml.sax.ContentHandler contentHandler,
LexicalHandler lexicalHandler)
throws IOException, SAXException, ProcessingException {
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN streamXMLFromURI uri=" + uri +
", typeParams="+typeParameters+
", parameters="+resourceParameters+
", contentHandler="+contentHandler+
", lexicalHandler="+lexicalHandler);
}
if (uri == null || uri.trim().length() == 0) {
throw new IllegalArgumentException("streamXMLFromURI: URI is
required");
}
long startTime = System.currentTimeMillis();
// Test for url rewriting
if (typeParameters != null
&& typeParameters.getParameter(URLRewriter.PARAMETER_MODE, null)
!= null) {
XMLConsumer consumer = new URLRewriter(typeParameters,
contentHandler,
lexicalHandler);
contentHandler = consumer;
lexicalHandler = consumer;
}
IncludeXMLConsumer filter = new IncludeXMLConsumer(contentHandler,
lexicalHandler);
Source input = null;
try {
input = this.getSource(uri, typeParameters, resourceParameters);
input.toSAX(filter);
} finally {
if (input != null) input.recycle();
input = null;
}
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END streamXMLFromURI");
}
}
/**
* Stream an XML resource.
* This is like loading the resource and then streaming it, but without
* the Resource->SAX->DOM->SAX transformation, its simply: Resource->SAX
*/
public void streamXML(int resourceType,
Parameters typeParameters,
String resourceIdentifier,
SourceParameters resourceParameters,
org.xml.sax.ContentHandler contentHandler,
LexicalHandler lexicalHandler)
throws ProcessingException {
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("start streaming
'"+resourceIdentifier+"'");
}
try {
switch (resourceType) {
case ResourceConnector.RESOURCE_TYPE_URI:
this.streamXMLFromURI(typeParameters,
resourceIdentifier, resourceParameters, contentHandler,
lexicalHandler);
break;
case ResourceConnector.RESOURCE_TYPE_CLASS:
throw new ProcessingException("streamXML: Type class not
implemented");
// break;
case ResourceConnector.RESOURCE_TYPE_FILE:
this.streamXMLFromFile(typeParameters,
resourceIdentifier, resourceParameters, contentHandler,
lexicalHandler);
break;
default: throw new ProcessingException("ResourceConnector: type "
+
resourceType + " not supported.");
}
} catch (SAXException ioe) {
throw new ProcessingException("SAXException: " + ioe, ioe);
} catch (IOException ioe) {
throw new ProcessingException("IOException: " + ioe, ioe);
}
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("finished streaming
'"+resourceIdentifier+"'");
}
}
/**
* Get the content of a uri
*/
private String getContentFromURI(Parameters typeParameters,
String uri,
SourceParameters resourceParameters)
throws SAXException, ProcessingException, IOException {
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN getContentFromURI uri=" + uri +
", typeParams="+typeParameters+
", parameters="+resourceParameters);
}
String content = null;
if (uri == null || uri.trim().length() == 0) {
throw new IllegalArgumentException("getContentFromURI: URI is
required");
}
long startTime = System.currentTimeMillis();
Source input = null;
try {
input = this.getSource(uri, typeParameters, resourceParameters);
InputSource source = input.getInputSource();
InputStream stream = source.getByteStream();
StringBuffer buffer = new StringBuffer();
String encoding = source.getEncoding();
int available;
byte[] data;
do {
available = 1024;
data = new byte[available];
available = stream.read(data, 0, available);
if (available > 0) {
if (encoding == null) {
buffer.append(new String(data, 0, available));
} else {
buffer.append(new String(data, 0, available,
encoding));
}
}
} while (available > 0);
content = buffer.toString();
} finally {
if (input != null) input.recycle();
input = null;
}
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END getContentFromURI content="+content);
}
return content;
}
/**
* Get the content of a file
*/
private String getContentFromFile(Parameters typeParameters,
String filename,
SourceParameters resourceParameters)
throws SAXException, ProcessingException, IOException {
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN getContentFromFile filename=" +
filename +
", typeParams="+typeParameters+
", parameters="+resourceParameters);
}
String content;
Source input = null;
try {
input = this.resolver.resolve(filename);
String absolutePath = input.getSystemId();
if (absolutePath.startsWith("file:") == false) {
throw new ProcessingException("Saving to " + filename + " is
not possible.");
}
File file = new File(absolutePath.substring("file:".length()));
byte[] data = null;
InputStream fis = new FileInputStream(file);
int available;
byte[] tempData;
byte[] copyData;
do {
available = 1024;
tempData = new byte[available];
available = fis.read(tempData, 0, available);
if (available > 0) {
copyData = new byte[(data == null ? 0 : data.length) +
available];
if (data != null) {
System.arraycopy(data, 0, copyData, 0, data.length);
}
System.arraycopy(tempData, 0, copyData, (data == null ? 0
: data.length), available);
data = copyData;
}
} while (available > 0);
fis.close();
content = (data == null ? "" : new String(data));
} catch (FileNotFoundException local) {
throw new ResourceNotFoundException("File not found '" + filename
+ "'", local);
} finally {
if (input != null) input.recycle();
input = null;
}
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END getContentFromFile content="+content);
}
return content;
}
/**
* Get the content
*/
public String getContent(int resourceType,
Parameters typeParameters,
String resourceIdentifier,
SourceParameters resourceParameters)
throws ProcessingException {
String content = null;
try {
switch (resourceType) {
case ResourceConnector.RESOURCE_TYPE_URI: content =
this.getContentFromURI(typeParameters,
resourceIdentifier, resourceParameters);
break;
case ResourceConnector.RESOURCE_TYPE_CLASS:
throw new ProcessingException("getContent: Type class not
implemented.");
case ResourceConnector.RESOURCE_TYPE_FILE: content =
this.getContentFromFile(typeParameters,
resourceIdentifier, resourceParameters);
break;
default: throw new ProcessingException("ResourceConnector:
type " +
resourceType + " not supported.");
}
} catch (SAXException local) {
throw new ProcessingException("SAXException: " + local, local);
} catch (IOException local) {
throw new ProcessingException("IOException: " + local, local);
}
return content;
}
/**
* Save a String to a resource.
*
* @param resourceType The type of the connection.
* @param typeParameters Connection Parameters.
* @param resourceIdentifier The resource name (filename, http address
etc)
* @param resourceParameters Parameters for the resource.
* @param content The data to be saved.
*/
public void saveContent(int resourceType,
Parameters typeParameters,
String resourceIdentifier,
SourceParameters resourceParameters,
String content)
throws ProcessingException {
try {
switch (resourceType) {
case ResourceConnector.RESOURCE_TYPE_URI:
this.saveContentToURI(typeParameters,
resourceIdentifier,
resourceParameters,
content);
break;
case ResourceConnector.RESOURCE_TYPE_CLASS:
throw new ProcessingException("saveContent: Type class
not implemented.");
case ResourceConnector.RESOURCE_TYPE_FILE:
this.saveContentToFile(typeParameters,
resourceIdentifier,
resourceParameters,
content);
break;
default: throw new ProcessingException("ResourceConnector:
type " +
resourceType + " not supported.");
}
} catch (SAXException local) {
throw new ProcessingException("SAXException: " + local, local);
} catch (IOException local) {
throw new ProcessingException("IOException: " + local, local);
}
}
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/webapps/session/connector/URLRewriter.java
Index: URLRewriter.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
[EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache
Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.cocoon.webapps.session.connector;
import java.net.MalformedURLException;
import java.net.URL;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.xml.XMLConsumer;
import org.xml.sax.ext.LexicalHandler;
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;
/**
* This is an <code>XMLConsumer</code> which rewrites the stream
* according to the configuration.
* The configuration can have the following parameters:
* "rewriteURLMode" : The mode to rewrite the urls. Currently none and cocoon
* are supported.
* "cocoonURL" : The url all links are resolved to
* "urlParameterName" : The parameter name to use for links (all links are
* then "cocoonURL?urlParameterName=LINK"
* "baseURL" : The current URL to rewrite
*
* @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
* @version CVS $Id: URLRewriter.java,v 1.1 2002/04/17 08:43:56 cziegeler Exp
$
*/
public final class URLRewriter implements XMLConsumer {
public static final String PARAMETER_MODE = "rewriteURLMode";
public static final String PARAMETER_PARAMETER_NAME = "urlParameterName";
public static final String PARAMETER_URL = "baseURL";
public static final String PARAMETER_COCOON_URL = "cocoonURL";
/** The <code>ContentHandler</code> */
private ContentHandler contentHandler;
/** The <code>LexicalHandler</code> */
private LexicalHandler lexicalHandler;
/** The mode:
* 0 : no rewriting
* 1 : cocoon */
private int mode;
/** The base url */
private String baseUrl;
/** The cocoon url */
private String cocoonUrl;
/**
* Create a new rewriter
*/
public URLRewriter(Parameters configuration,
ContentHandler contentHandler,
LexicalHandler lexicalHandler)
throws ProcessingException {
try {
this.contentHandler = contentHandler;
this.lexicalHandler = lexicalHandler;
this.mode = 0;
if (configuration != null
&& configuration.getParameter(PARAMETER_MODE, null) != null) {
if (configuration.getParameter(PARAMETER_MODE,
null).equalsIgnoreCase("cocoon") == true) {
this.mode = 1;
this.baseUrl = configuration.getParameter(PARAMETER_URL);
this.cocoonUrl =
configuration.getParameter(PARAMETER_COCOON_URL) +
'?' +
configuration.getParameter(PARAMETER_PARAMETER_NAME) + '=';
}
}
} catch (org.apache.avalon.framework.parameters.ParameterException
local) {
throw new ProcessingException("URLRewriter: configuration
exception.", local);
}
}
/**
* SAX Event Handling
*/
public void setDocumentLocator(Locator locator) {
contentHandler.setDocumentLocator(locator);
}
/**
* SAX Event Handling
*/
public void startDocument()
throws SAXException {
contentHandler.startDocument();
}
/**
* SAX Event Handling
*/
public void endDocument()
throws SAXException {
contentHandler.endDocument();
}
/**
* SAX Event Handling
*/
public void startPrefixMapping(String prefix, String uri)
throws SAXException {
contentHandler.startPrefixMapping(prefix,uri);
}
/**
* SAX Event Handling
*/
public void endPrefixMapping(String prefix)
throws SAXException {
contentHandler.endPrefixMapping(prefix);
}
/**
* SAX Event Handling
*/
public void startElement(String namespace, String name, String raw,
Attributes attr)
throws SAXException {
if (this.mode == 1) {
String url;
String attrname;
AttributesImpl newattr = null;
String value;
for(int i = 0; i < attr.getLength(); i++) {
attrname = attr.getLocalName(i);
if (attrname.equals("href") == true
|| attrname.equals("action") == true) {
if (newattr == null) {
newattr = new AttributesImpl(attr);
}
value = attr.getValue(i);
if (value.indexOf(':') == -1) {
try {
URL baseURL = new URL(new URL(this.baseUrl),
value);
value = baseURL.toExternalForm();
} catch (MalformedURLException local) {
value = attr.getValue(i);
}
}
newattr.setValue(i, this.cocoonUrl + value);
} else if (attrname.equals("src") == true
|| attrname.equals("background") == true) {
if (newattr == null) {
newattr = new AttributesImpl(attr);
}
value = attr.getValue(i);
if (value.indexOf(':') == -1) {
try {
URL baseURL = new URL(new URL(this.baseUrl),
value);
value = baseURL.toExternalForm();
} catch (MalformedURLException local) {
value = attr.getValue(i);
}
}
newattr.setValue(i, value);
}
}
if (newattr != null) {
contentHandler.startElement(namespace, name, raw, newattr);
return;
}
}
contentHandler.startElement(namespace,name,raw,attr);
}
/**
* SAX Event Handling
*/
public void endElement(String namespace, String name, String raw)
throws SAXException {
contentHandler.endElement(namespace,name,raw);
}
/**
* SAX Event Handling
*/
public void characters(char ary[], int start, int length)
throws SAXException {
contentHandler.characters(ary,start,length);
}
/**
* SAX Event Handling
*/
public void ignorableWhitespace(char ary[], int start, int length)
throws SAXException {
contentHandler.ignorableWhitespace(ary,start,length);
}
/**
* SAX Event Handling
*/
public void processingInstruction(String target, String data)
throws SAXException {
contentHandler.processingInstruction(target,data);
}
/**
* SAX Event Handling
*/
public void skippedEntity(String name)
throws SAXException {
contentHandler.skippedEntity(name);
}
/**
* SAX Event Handling
*/
public void startDTD(String name, String public_id, String system_id)
throws SAXException {
if (lexicalHandler != null)
lexicalHandler.startDTD(name,public_id,system_id);
}
/**
* SAX Event Handling
*/
public void endDTD() throws SAXException {
if (lexicalHandler != null) lexicalHandler.endDTD();
}
/**
* SAX Event Handling
*/
public void startEntity(String name) throws SAXException {
if (lexicalHandler != null) lexicalHandler.startEntity(name);
}
/**
* SAX Event Handling
*/
public void endEntity(String name) throws SAXException {
if (lexicalHandler != null) lexicalHandler.endEntity(name);
}
/**
* SAX Event Handling
*/
public void startCDATA() throws SAXException {
if (lexicalHandler != null) lexicalHandler.startCDATA();
}
/**
* SAX Event Handling
*/
public void endCDATA() throws SAXException {
if (lexicalHandler != null) lexicalHandler.endCDATA();
}
/**
* SAX Event Handling
*/
public void comment(char ary[], int start, int length)
throws SAXException {
if (this.lexicalHandler != null) {
lexicalHandler.comment(ary,start,length);
}
}
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/webapps/session/connector/XMLLoader.java
Index: XMLLoader.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
[EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache
Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.cocoon.webapps.session.connector;
import java.util.Map;
import org.apache.avalon.excalibur.source.SourceParameters;
import org.w3c.dom.DocumentFragment;
import org.apache.cocoon.ProcessingException;
/**
* Interface for loading xml - NOT USED YET
*
* @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
* @version CVS $Id: XMLLoader.java,v 1.1 2002/04/17 08:43:56 cziegeler Exp $
*/
public interface XMLLoader {
/**
* Load a DocumentFragment
*/
DocumentFragment load(Map objectModel,
SourceParameters parameters)
throws ProcessingException;
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/webapps/session/connector/XMLSaver.java
Index: XMLSaver.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
[EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache
Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.cocoon.webapps.session.connector;
import java.util.Map;
import org.apache.avalon.excalibur.source.SourceParameters;
import org.w3c.dom.DocumentFragment;
import org.apache.cocoon.ProcessingException;
/**
* Interface for saving xml - NOT USED YET
*
* @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
* @version CVS $Id: XMLSaver.java,v 1.1 2002/04/17 08:43:56 cziegeler Exp $
*/
public interface XMLSaver {
/**
* Save a DocumentFragment
*/
void save(DocumentFragment fragment,
Map session,
SourceParameters parameter)
throws ProcessingException;
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/webapps/session/context/RequestSessionContext.java
Index: RequestSessionContext.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
[EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache
Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.cocoon.webapps.session.context;
import java.io.*;
import java.util.*;
import org.apache.avalon.excalibur.xml.Parser;
import org.apache.avalon.excalibur.source.SourceParameters;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.component.ComponentException;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.environment.Cookie;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.cocoon.environment.http.HttpRequest;
import org.apache.cocoon.webapps.session.SessionConstants;
import org.apache.cocoon.webapps.session.connector.Resource;
import org.apache.cocoon.webapps.session.xml.XMLUtil;
import org.apache.cocoon.xml.IncludeXMLConsumer;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.SAXException;
import org.xml.sax.ContentHandler;
import org.xml.sax.ext.LexicalHandler;
/**
* A SessionContext which encapsulates the current Request object.
*
* It is not allowed to change this context.
* The following paths are valid:
* /parameter - lists all parameters, parameter names build
the
* elements with the values as text node childs
* /parameter/<parameter_name> - one text node containing the value
* /querystring - the querystring with a leading '?' or null
(the querystring is only for GET)
*
* /parametervalues - same as /parameter but values are listed as
described
* below
* <session:params>
* <session:param>
* <session:name>parameter
name</session:name>
* <session:value>parameter
value</session:value>
* </session:param>
* ...
* <session:param>
* <session:name>parameter
name</session:name>
* <session:value>parameter
value</session:value>
* </session:param>
* </session:params>
* If a parameter has more than one value for
each value a
* <session:param> block is generated.
* /attributes - lists all attributes, attribute names build the elements
* with the values as text node childs
* /headers - lists all headers, header names build the elements
* with the values as text node childs
* /cookies ----- <cookie name="...">
* <comment/>
* <domain/>
* <maxAge/>
* <name/>
* <path/>
* <secure/>
* <value/>
* <version/>
* /characterEncoding
* /contentLength
* /contentType
* /protocol
* /remoteAddress
* /remoteHost
* /scheme
* /serverName
* /serverPort
* /authType <!-- only for http -->
* /method
* /contextPath
* /pathInfo
* /pathTranslated
* /remoteUser
* /requestedSessionId
* /requestURI
* /servletPath
* /isRequestedSessionIdFromCookie
* /isRequestedSessionIdFromCookie
* /isRequestedSessionIdValid
*
* The following attributes of the servlet api 2.2 are missing:
* - getUserPrincipal()
* - getLocale()
* - getLocales()
*
* @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
* @version CVS $Id: RequestSessionContext.java,v 1.1 2002/04/17 08:43:57
cziegeler Exp $
*/
public final class RequestSessionContext
implements SessionContext {
private String name;
transient private Request request;
private Document contextData;
public void setup(String value, Resource load, Resource save) { name =
value; }
/**
* Set the Request
*/
public void setup(Map objectModel, ComponentManager manager)
throws ProcessingException {
this.request = ObjectModelHelper.getRequest(objectModel);
contextData = XMLUtil.createDocument();
contextData.appendChild(contextData.createElementNS(null, "context"));
Element root = contextData.getDocumentElement();
Parser parser = null;
try {
parser = (Parser) manager.lookup( Parser.ROLE );
this.buildParameterXML(root, parser);
} catch (ComponentException ce) {
throw new ProcessingException("Unable to lookup parser.", ce);
} finally {
manager.release( parser );
}
this.buildAttributesXML(root);
this.buildMiscXML(root);
this.buildCookiesXML(root);
this.buildHeadersXML(root);
}
/**
* Get the name of the context
*/
public String getName() {
return this.name;
}
/**
* Build path
*/
private String createPath(String path) {
if (path == null) path = "/";
if (path.startsWith("/") == false) path = "/" + path;
path = "/context" + path;
if (path.endsWith("/") == true) path = path.substring(0,
path.length() - 1);
return path;
}
private Node createTextNode(Document doc, String value) {
return doc.createTextNode(value != null ? value : "");
}
/**
* Build attributes XML
*/
private void buildMiscXML(Element root)
throws ProcessingException {
Document doc = root.getOwnerDocument();
Element node;
node = doc.createElementNS(null, "characterEncoding");
node.appendChild(this.createTextNode(doc,
this.request.getCharacterEncoding()));
root.appendChild(node);
node = doc.createElementNS(null, "contentLength");
node.appendChild(this.createTextNode(doc, "" +
this.request.getContentLength()));
root.appendChild(node);
node = doc.createElementNS(null, "contentType");
node.appendChild(this.createTextNode(doc,
this.request.getContentType()));
root.appendChild(node);
node = doc.createElementNS(null, "protocol");
node.appendChild(this.createTextNode(doc,
this.request.getProtocol()));
root.appendChild(node);
node = doc.createElementNS(null, "remoteAddress");
node.appendChild(this.createTextNode(doc,
this.request.getRemoteAddr()));
root.appendChild(node);
node = doc.createElementNS(null, "remoteHost");
node.appendChild(this.createTextNode(doc,
this.request.getRemoteHost()));
root.appendChild(node);
node = doc.createElementNS(null, "scheme");
node.appendChild(this.createTextNode(doc,
this.request.getRemoteHost()));
root.appendChild(node);
node = doc.createElementNS(null, "serverName");
node.appendChild(this.createTextNode(doc,
this.request.getServerName()));
root.appendChild(node);
node = doc.createElementNS(null, "serverPort");
node.appendChild(this.createTextNode(doc,
""+this.request.getServerPort()));
root.appendChild(node);
if (this.request instanceof HttpRequest) {
node = doc.createElementNS(null, "authType");
node.appendChild(this.createTextNode(doc,
((HttpRequest)this.request).getAuthType()));
root.appendChild(node);
}
node = doc.createElementNS(null, "method");
node.appendChild(this.createTextNode(doc, this.request.getMethod()));
root.appendChild(node);
node = doc.createElementNS(null, "contextPath");
node.appendChild(this.createTextNode(doc,
this.request.getContextPath()));
root.appendChild(node);
node = doc.createElementNS(null, "pathInfo");
node.appendChild(this.createTextNode(doc,
this.request.getPathInfo()));
root.appendChild(node);
node = doc.createElementNS(null, "pathTranslated");
node.appendChild(this.createTextNode(doc,
this.request.getPathTranslated()));
root.appendChild(node);
node = doc.createElementNS(null, "remoteUser");
node.appendChild(this.createTextNode(doc,
this.request.getRemoteUser()));
root.appendChild(node);
node = doc.createElementNS(null, "requestedSessionId");
node.appendChild(this.createTextNode(doc,
this.request.getRequestedSessionId()));
root.appendChild(node);
node = doc.createElementNS(null, "requestURI");
node.appendChild(this.createTextNode(doc,
this.request.getRequestURI()));
root.appendChild(node);
node = doc.createElementNS(null, "servletPath");
node.appendChild(this.createTextNode(doc,
this.request.getServletPath()));
root.appendChild(node);
node = doc.createElementNS(null, "isRequestedSessionIdFromCookie");
node.appendChild(doc.createTextNode(this.request.isRequestedSessionIdFromCookie()
? "true" : "false"));
root.appendChild(node);
node = doc.createElementNS(null, "isRequestedSessionIdFromURL");
node.appendChild(doc.createTextNode(this.request.isRequestedSessionIdFromURL()
? "true" : "false"));
root.appendChild(node);
node = doc.createElementNS(null, "isRequestedSessionIdValid");
node.appendChild(doc.createTextNode(this.request.isRequestedSessionIdValid() ?
"true" : "false"));
root.appendChild(node);
}
/**
* Build attributes XML
*/
private void buildAttributesXML(Element root)
throws ProcessingException {
Document doc = root.getOwnerDocument();
Element attrElement = doc.createElementNS(null, "attributes");
String attrName;
Element attr;
root.appendChild(attrElement);
Enumeration all = this.request.getAttributeNames();
while (all.hasMoreElements() == true) {
attrName = (String) all.nextElement();
attr = doc.createElementNS(null, attrName);
attrElement.appendChild(attr);
attr.appendChild(this.createTextNode(doc,
this.request.getAttribute(attrName).toString()));
}
}
/**
* Build cookies XML
*/
private void buildCookiesXML(Element root)
throws ProcessingException {
Document doc = root.getOwnerDocument();
Element cookiesElement = doc.createElementNS(null, "cookies");
root.appendChild(cookiesElement);
Cookie[] cookies = this.request.getCookies();
if (cookies != null) {
Cookie current;
Element node;
Element parent;
for(int i = 0; i < cookies.length; i++) {
current = cookies[i];
parent = doc.createElementNS(null, "cookie");
parent.setAttributeNS(null, "name", current.getName());
cookiesElement.appendChild(parent);
node = doc.createElementNS(null, "comment");
node.appendChild(this.createTextNode(doc,
current.getComment()));
parent.appendChild(node);
node = doc.createElementNS(null, "domain");
node.appendChild(this.createTextNode(doc,
current.getDomain()));
parent.appendChild(node);
node = doc.createElementNS(null, "maxAge");
node.appendChild(this.createTextNode(doc,
""+current.getMaxAge()));
parent.appendChild(node);
node = doc.createElementNS(null, "name");
node.appendChild(this.createTextNode(doc, current.getName()));
parent.appendChild(node);
node = doc.createElementNS(null, "path");
node.appendChild(this.createTextNode(doc, current.getPath()));
parent.appendChild(node);
node = doc.createElementNS(null, "secure");
node.appendChild(doc.createTextNode(current.getSecure() ?
"true" : "false"));
parent.appendChild(node);
node = doc.createElementNS(null, "value");
node.appendChild(this.createTextNode(doc,
current.getValue()));
parent.appendChild(node);
node = doc.createElementNS(null, "version");
node.appendChild(this.createTextNode(doc,
""+current.getVersion()));
parent.appendChild(node);
}
}
}
/**
* Build headers XML
*/
private void buildHeadersXML(Element root)
throws ProcessingException {
Document doc = root.getOwnerDocument();
Element headersElement = doc.createElementNS(null, "headers");
String headerName;
Element header;
root.appendChild(headersElement);
Enumeration all = this.request.getHeaderNames();
while (all.hasMoreElements() == true) {
headerName = (String) all.nextElement();
header = doc.createElementNS(null, headerName);
headersElement.appendChild(header);
header.appendChild(this.createTextNode(doc,
this.request.getHeader(headerName)));
}
}
/**
* Build parameter XML
*/
private void buildParameterXML(Element root, Parser parser)
throws ProcessingException {
Document doc = root.getOwnerDocument();
// include all parameters
// process "/parameter" and "/parametervalues" at the same time
Element parameterElement = doc.createElementNS(null, "parameter");
Element parameterValuesElement = doc.createElementNS(null,
"parametervalues");
root.appendChild(parameterElement);
root.appendChild(parameterValuesElement);
String parameterName = null;
Enumeration pars = this.request.getParameterNames();
Element parameter;
Element element;
Node valueNode;
String[] values;
String parValue;
element = doc.createElementNS(SessionConstants.SESSION_NAMESPACE_URI,
"session:params");
parameterValuesElement.appendChild(element);
parameterValuesElement = element;
while (pars.hasMoreElements() == true) {
parameterName = (String)pars.nextElement();
values = this.request.getParameterValues(parameterName);
for(int i = 0; i < values.length; i++) {
// this is a fast test, if the parameter value contains xml!
parValue = values[i].trim();
if (parValue.length() > 0 && parValue.charAt(0) == '<') {
try {
valueNode = XMLUtil.getDocumentFragment(parser, new
StringReader(parValue));
valueNode = doc.importNode(valueNode, true);
} catch (Exception noXMLException) {
valueNode = doc.createTextNode(parValue);
}
} else {
valueNode = doc.createTextNode(parValue);
}
// create "/parameter" entry for first value
if (i == 0) {
try {
parameter = doc.createElementNS(null, parameterName);
parameter.appendChild(valueNode);
parameterElement.appendChild(parameter);
} catch (Exception local) {
// the exception is ignored and only this parameters
is ignored
}
}
try {
// create "/parametervalues" entry
element =
doc.createElementNS(SessionConstants.SESSION_NAMESPACE_URI, "cocoon:param");
parameterValuesElement.appendChild(element);
parameter = element;
element =
doc.createElementNS(SessionConstants.SESSION_NAMESPACE_URI, "cocoon:name");
parameter.appendChild(element);
element.appendChild(doc.createTextNode(parameterName));
element =
doc.createElementNS(SessionConstants.SESSION_NAMESPACE_URI, "cocoon:value");
parameter.appendChild(element);
element.appendChild(valueNode.cloneNode(true));
} catch (Exception local) {
// the exception is ignored and only this parameters is
ignored
}
}
}
// and now the query string
element = doc.createElementNS(null, "querystring");
root.appendChild(element);
String value = request.getQueryString();
if (value != null) {
element.appendChild(doc.createTextNode('?' + value));
}
}
/**
* Get the XML from the request object
*/
public DocumentFragment getXML(String path)
throws ProcessingException {
if (path == null || path.charAt(0) != '/') {
throw new ProcessingException("Not a valid XPath: " + path);
}
path = this.createPath(path);
DocumentFragment result = null;
NodeList list;
try {
list = XMLUtil.selectNodeList(this.contextData, path);
} catch (javax.xml.transform.TransformerException localException) {
throw new ProcessingException("Exception: " + localException,
localException);
}
if (list != null && list.getLength() > 0) {
result =
XMLUtil.getOwnerDocument(contextData).createDocumentFragment();
for(int i = 0; i < list.getLength(); i++) {
// the found node is either an attribute or an element
if (list.item(i).getNodeType() == Node.ATTRIBUTE_NODE) {
// if it is an attribute simple create a new text node
with the value of the attribute
result.appendChild(XMLUtil.getOwnerDocument(contextData).createTextNode(list.item(i).getNodeValue()));
} else {
// now we have an element
// copy all children of this element in the resulting tree
NodeList childs = list.item(i).getChildNodes();
if (childs != null) {
for(int m = 0; m < childs.getLength(); m++) {
result.appendChild(XMLUtil.getOwnerDocument(contextData).importNode(childs.item(m),
true));
}
}
}
}
}
return result;
}
/**
* Setting of xml is not possible for the request context
*/
public void setXML(String path, DocumentFragment fragment)
throws ProcessingException {
throw new ProcessingException("RequestSessionContext: Setting of xml
not allowed");
}
/**
* Setting of xml is not possible for the request context
*/
public void setValueOfNode(String path, String value)
throws ProcessingException {
throw new ProcessingException("RequestSessionContext: Setting of xml
not allowed");
}
/**
* Append a document fragment is not possible for the request context.
*/
public void appendXML(String path, DocumentFragment fragment)
throws ProcessingException {
throw new ProcessingException("RequestSessionContext: Appending of
xml not allowed");
}
/**
* Removing is not possible for the request context.
*/
public void removeXML(String path)
throws ProcessingException {
throw new ProcessingException("RequestSessionContext: Removing of xml
not allowed");
}
/**
* Set a context attribute. If value is null the attribute is removed.
*/
public void setAttribute(String key, Object value)
throws ProcessingException {
if (value == null) {
this.request.removeAttribute(key);
} else {
this.request.setAttribute(key, value);
}
}
/**
* Get a context attribute. If the attribute is not available return null
*/
public Object getAttribute(String key)
throws ProcessingException {
return this.request.getAttribute(key);
}
/**
* Get a context attribute. If the attribute is not available the
defaultObject is returned
*/
public Object getAttribute(String key, Object defaultObject)
throws ProcessingException {
Object obj = this.getAttribute(key);
return (obj != null ? obj : defaultObject);
}
/**
* Get a copy the first node specified by the path.
*/
public Node getSingleNode(String path)
throws ProcessingException {
path = this.createPath(path);
Node node = null;
try {
node = XMLUtil.getSingleNode(this.contextData, path);
} catch (javax.xml.transform.TransformerException localException) {
throw new ProcessingException("Exception: " + localException,
localException);
}
return node;
}
/**
* Get a copy all the nodes specified by the path.
*/
public NodeList getNodeList(String path)
throws ProcessingException {
path = this.createPath(path);
NodeList list = null;
try {
list = XMLUtil.selectNodeList(this.contextData, path);
} catch (javax.xml.transform.TransformerException localException) {
throw new ProcessingException("Exception: " + localException,
localException);
}
return list;
}
/**
* Set the value of a node. The node is copied before insertion.
*/
public void setNode(String path, Node node)
throws ProcessingException {
throw new ProcessingException("RequestSessionContext: Setting of XML
not allowed");
}
/**
* Get the value of this node. This is similiar to the xsl:value-of
* function. If the node does not exist, <code>null</code> is returned.
*/
public String getValueOfNode(String path)
throws ProcessingException {
String value = null;
Node node = this.getSingleNode(path);
if (node != null) {
value = XMLUtil.getValueOfNode(node);
}
return value;
}
/**
* Stream the XML directly to the handler. This streams the contents of
getXML()
* to the given handler without creating a DocumentFragment containing a
copy
* of the data
*/
public boolean streamXML(String path,
ContentHandler contentHandler,
LexicalHandler lexicalHandler)
throws SAXException, ProcessingException {
boolean result = false;
NodeList list;
try {
list = XMLUtil.selectNodeList(this.contextData,
this.createPath(path));
} catch (javax.xml.transform.TransformerException local) {
throw new ProcessingException("TransformerException: " + local,
local);
}
if (list != null && list.getLength() > 0) {
result = true;
for(int i = 0; i < list.getLength(); i++) {
// the found node is either an attribute or an element
if (list.item(i).getNodeType() == Node.ATTRIBUTE_NODE) {
// if it is an attribute simple create a new text node
with the value of the attribute
String value = list.item(i).getNodeValue();
contentHandler.characters(value.toCharArray(), 0,
value.length());
} else {
// now we have an element
// stream all children of this element to the resulting
tree
NodeList childs = list.item(i).getChildNodes();
if (childs != null) {
for(int m = 0; m < childs.getLength(); m++) {
IncludeXMLConsumer.includeNode(childs.item(m),
contentHandler, lexicalHandler);
}
}
}
}
}
return result;
}
/**
* Get the request parameter as xml
*/
public DocumentFragment getParameterAsXML(final String parameterName)
throws ProcessingException {
return this.getXML("/parameter/"+parameterName);
}
/**
* Get the request parameter as a String
*/
public String getParameter(final String parameterName)
throws ProcessingException {
return this.request.getParameter(parameterName);
}
/**
* Try to load XML into the context.
* If the context does not provide the ability of loading,
* an exception is thrown.
*/
public void loadXML(String path,
SourceParameters parameters,
Map objectModel,
SourceResolver resolver,
ComponentManager manager)
throws SAXException, ProcessingException, IOException {
throw new ProcessingException("The context " + this.name + " does not
support loading.");
}
/**
* Try to save XML from the context.
* If the context does not provide the ability of saving,
* an exception is thrown.
*/
public void saveXML(String path,
SourceParameters parameters,
Map objectModel,
SourceResolver resolver,
ComponentManager manager)
throws SAXException, ProcessingException, IOException {
throw new ProcessingException("The context " + this.name + " does not
support saving.");
}
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/webapps/session/context/ResponseSessionContext.java
Index: ResponseSessionContext.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
[EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache
Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.cocoon.webapps.session.context;
import java.io.IOException;
import java.util.Map;
import org.apache.avalon.excalibur.source.SourceParameters;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.environment.Cookie;
import org.apache.cocoon.environment.Response;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.cocoon.webapps.session.connector.Resource;
import org.apache.cocoon.webapps.session.xml.XMLUtil;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.xml.sax.ContentHandler;
import org.xml.sax.ext.LexicalHandler;
/**
* A SessionContext which encapsulates the current Response object.
*
* The following XML for setXML and appendXML is allowed:
* /header/<headername> - The content is the value of the header
* /cookie - The content is the cookie:
* <name>gsdgsdg</name> - name of the cookie
* <value>gdgdgdgs</value> - cookie value
* optional:
* <domain/>
* <path/>
* <secure>true or false</secure>
* <comment/>
* <version/>
* <maxAge/>
*
* Using setXML uses setHeader() and appendXML uses addHeader. Despite this
they
* both have the same effect.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
* @version CVS $Id: ResponseSessionContext.java,v 1.1 2002/04/17 08:43:57
cziegeler Exp $
*/
public final class ResponseSessionContext
implements SessionContext {
private String name;
transient private Response response;
public void setup(String value, Resource load, Resource save) {
name = value;
}
public void setup(Map objectModel) {
this.response = ObjectModelHelper.getResponse(objectModel);
}
/**
* Get the name of the context
*/
public String getName() {
return this.name;
}
/**
* Build the cookie
*/
private Cookie createCookie(SourceParameters par) {
Cookie cookie = this.response.createCookie(par.getParameter("name"),
par.getParameter("value"));
String value;
value = par.getParameter("comment");
if (value != null) cookie.setComment(value);
value = par.getParameter("domain");
if (value != null) cookie.setDomain(value);
value = par.getParameter("path");
if (value != null) cookie.setPath(value);
if (par.containsParameter("maxAge") == true) {
cookie.setMaxAge(par.getParameterAsInteger("maxAge", 0));
}
if (par.containsParameter("version") == true) {
cookie.setVersion(par.getParameterAsInteger("version", 0));
}
if (par.containsParameter("secure") == true) {
cookie.setSecure(par.getParameterAsBoolean("secure", true));
}
return cookie;
}
/**
* Get the XML from the response object
*/
public DocumentFragment getXML(String path)
throws ProcessingException {
throw new ProcessingException("ResponseSessionContext: Getting of xml
not allowed.");
}
public void setXML(String path, DocumentFragment fragment)
throws ProcessingException {
if (this.response == null) {
throw new ProcessingException("Response Object missing");
}
if (path != null) {
if (path.startsWith("/header/") == true) {
String name = path.substring(8);
this.response.setHeader(name, XMLUtil.createText(fragment));
} else if (path.equals("/cookie") == true) {
this.response.addCookie(this.createCookie(XMLUtil.createParameters(fragment,
null)));
} else {
throw new ProcessingException("Invalid response path
'"+path+"'");
}
}
}
/**
* Append a document fragment at the given path. The implementation of
this
* method is context specific.
*/
public void appendXML(String path, DocumentFragment fragment)
throws ProcessingException {
if (this.response == null) {
throw new ProcessingException("Response Object missing");
}
if (path != null) {
if (path.startsWith("/header/") == true) {
String name = path.substring(8);
this.response.addHeader(name, XMLUtil.createText(fragment));
} else if (path.equals("/cookie") == true) {
this.response.addCookie(this.createCookie(XMLUtil.createParameters(fragment,
null)));
} else {
throw new ProcessingException("Invalid response path
'"+path+"'");
}
}
}
public void removeXML(String path)
throws ProcessingException {
throw new ProcessingException("ResponseSessionContext: Removing of
xml not allowed");
}
/**
* Set a context attribute.
*/
public void setAttribute(String key, Object value)
throws ProcessingException {
throw new ProcessingException("ResponseSessionContext: Setting of
attributes not allowed");
}
/**
* Get a context attribute.
*/
public Object getAttribute(String key)
throws ProcessingException {
throw new ProcessingException("ResponseSessionContext: Getting of
attributes not allowed");
}
/**
* Get a context attribute.
*/
public Object getAttribute(String key, Object defaultObject)
throws ProcessingException {
throw new ProcessingException("ResponseSessionContext: Getting of
attributes not allowed");
}
/**
* Get a copy the first node specified by the path.
*/
public Node getSingleNode(String path)
throws ProcessingException {
throw new ProcessingException("ResponseSessionContext: Getting of xml
not allowed");
}
/**
* Get a copy all the nodes specified by the path.
*/
public NodeList getNodeList(String path)
throws ProcessingException {
throw new ProcessingException("ResponseSessionContext: Getting of xml
not allowed");
}
/**
* Set the value of a node. The node is copied before insertion.
*/
public void setNode(String path, Node node)
throws ProcessingException {
throw new ProcessingException("ResponseSessionContext: Setting of XML
not allowed");
}
/**
* Get the value of this node. This is similiar to the xsl:value-of
* function. If the node does not exist, <code>null</code> is returned.
*/
public String getValueOfNode(String path)
throws ProcessingException {
throw new ProcessingException("ResponseSessionContext: Getting of xml
not allowed");
}
/**
* Set the value of this node.
*/
public void setValueOfNode(String path, String value)
throws ProcessingException {
throw new ProcessingException("ResponseSessionContext: Setting of xml
not allowed");
}
/**
* Stream the XML directly to the handler. This streams the contents of
getXML()
* to the given handler without creating a DocumentFragment containing a
copy
* of the data
*/
public boolean streamXML(String path,
ContentHandler contentHandler,
LexicalHandler lexicalHandler)
throws SAXException, ProcessingException {
throw new ProcessingException("ResponseSessionContext: Getting of xml
not allowed");
}
/**
* Try to load XML into the context.
* If the context does not provide the ability of loading,
* an exception is thrown.
*/
public void loadXML(String path,
SourceParameters parameters,
Map objectModel,
SourceResolver resolver,
ComponentManager manager)
throws SAXException, ProcessingException, IOException {
throw new ProcessingException("The context " + this.name + " does not
support loading.");
}
/**
* Try to save XML from the context.
* If the context does not provide the ability of saving,
* an exception is thrown.
*/
public void saveXML(String path,
SourceParameters parameters,
Map objectModel,
SourceResolver resolver,
ComponentManager manager)
throws SAXException, ProcessingException, IOException {
throw new ProcessingException("The context " + this.name + " does not
support saving.");
}
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/webapps/session/context/SessionContext.java
Index: SessionContext.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
[EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache
Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.cocoon.webapps.session.context;
import java.io.IOException;
import java.io.Serializable;
import java.util.Map;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.xml.sax.ContentHandler;
import org.xml.sax.ext.LexicalHandler;
import org.apache.avalon.excalibur.source.SourceParameters;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.cocoon.webapps.session.connector.Resource;
/**
* Interface for a SessionContext.
* This interface describes a SessionContext. The SessionContext is a data
* container containing structured XML which can be retrieved/set by the
* session transformer.
* This interface does not specify how the session context stores the data.
* This is left to the implementation itself, but actually this interface
* is build in the DOM model.
* As this context is used in a web context, all methods must be
synchronized.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
* @version CVS $Id: SessionContext.java,v 1.1 2002/04/17 08:43:57 cziegeler
Exp $
*/
public interface SessionContext
extends Serializable {
/** Set the name of the context.
* This method must be invoked in the init phase.
* In addition a load and a save resource can be provided.
*/
void setup(String value, Resource load, Resource save);
/**
* Get the name of the context
*/
String getName();
/**
* Get a document fragment.
* If the node specified by the path exist, its content is returned
* as a DocumentFragment.
* If the node does not exists, <CODE>null</CODE> is returned.
*/
DocumentFragment getXML(String path)
throws ProcessingException ;
/**
* Set a document fragment at the given path.
* The implementation of this method is context specific.
* Usually all children of the node specified by the path are removed
* and the children of the fragment are inserted as new children.
* If the path is not existent it is created.
*/
void setXML(String path, DocumentFragment fragment)
throws ProcessingException;
/**
* Append a document fragment at the given path.
* The implementation of this method is context specific.
* Usually the children of the fragment are appended as new children of
the
* node specified by the path.
* If the path is not existent it is created and this method should work
* in the same way as setXML.
*/
void appendXML(String path, DocumentFragment fragment)
throws ProcessingException;
/**
* Remove some content from the context.
* The implementation of this method is context specific.
* Usually this method should remove all children of the node specified
* by the path.
*/
void removeXML(String path)
throws ProcessingException;
/**
* Set a context attribute.
* Attributes over a means to store any data (object) in a session
* context. If <CODE>value</CODE> is <CODE>null</CODE> the attribute is
* removed. If already an attribute exists with the same key, the value
* is overwritten with the new one.
*/
void setAttribute(String key, Object value)
throws ProcessingException;
/**
* Get the value of a context attribute.
* If the attribute is not available return <CODE>null</CODE>.
*/
Object getAttribute(String key)
throws ProcessingException;
/**
* Get the value of a context attribute.
* If the attribute is not available the return the
* <CODE>defaultObject</CODE>.
*/
Object getAttribute(String key, Object defaultObject)
throws ProcessingException;
/**
* Get a copy of the first node specified by the path.
* If the node does not exist, <CODE>null</CODE> is returned.
*/
Node getSingleNode(String path)
throws ProcessingException;
/**
* Get a copy of all nodes specified by the path.
*/
NodeList getNodeList(String path)
throws ProcessingException;
/**
* Set the value of a node. The node is copied before insertion.
*/
void setNode(String path, Node node)
throws ProcessingException;
/**
* Get the value of this node.
* This is similiar to the xsl:value-of function.
* If the node does not exist, <code>null</code> is returned.
*/
String getValueOfNode(String path)
throws ProcessingException;
/**
* Set the value of a node.
* All children of the node are removed beforehand and one single text
* node with the given value is appended to the node.
*/
void setValueOfNode(String path, String value)
throws ProcessingException;
/**
* Stream the XML directly to the handler.
* This streams the contents of getXML() to the given handler without
* creating a DocumentFragment containing a copy of the data.
* If no data is available (if the path does not exist)
<code>false</code> is
* returned, otherwise <code>true</code>.
*/
boolean streamXML(String path,
ContentHandler contentHandler,
LexicalHandler lexicalHandler)
throws SAXException, ProcessingException;
/**
* Try to load XML into the context.
* If the context does not provide the ability of loading,
* an exception is thrown.
*/
void loadXML(String path,
SourceParameters parameters,
Map objectModel,
SourceResolver resolver,
ComponentManager manager)
throws SAXException, ProcessingException, IOException;
/**
* Try to save XML from the context.
* If the context does not provide the ability of saving,
* an exception is thrown.
*/
void saveXML(String path,
SourceParameters parameters,
Map objectModel,
SourceResolver resolver,
ComponentManager manager)
throws SAXException, ProcessingException, IOException;
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/webapps/session/context/SessionContextProvider.java
Index: SessionContextProvider.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
[EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache
Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.cocoon.webapps.session.context;
import java.util.Map;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.environment.SourceResolver;
/**
* Interface for a context provider.
* Objects of this class provide special context, e.g. sunRise or sunSpot.
* The context is (if used) got once by the <code>SessionManager</code>
component
* for each request.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
* @version CVS $Id: SessionContextProvider.java,v 1.1 2002/04/17 08:43:57
cziegeler Exp $
*/
public interface SessionContextProvider {
/**
* Get the context
* @param name The name of the context
* @param objectModel The objectModel of the current request.
* @param resolver The source resolver
* @param componentManager manager
* @result The context
* @throws ProcessingException If the context is not available.
*/
SessionContext getSessionContext(String name,
Map objectModel,
SourceResolver resolver,
ComponentManager manager)
throws ProcessingException;
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/webapps/session/context/SimpleSessionContext.java
Index: SimpleSessionContext.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
[EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache
Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.cocoon.webapps.session.context;
import java.io.IOException;
import java.util.*;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.xml.sax.ContentHandler;
import org.xml.sax.ext.LexicalHandler;
import org.apache.xpath.XPathContext;
import org.apache.xpath.XPath;
import org.apache.xpath.XPathContext;
import org.apache.xml.utils.PrefixResolverDefault;
import org.apache.xpath.objects.XObject;
import org.apache.avalon.excalibur.source.SourceParameters;
import org.apache.avalon.framework.component.ComponentException;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.cocoon.webapps.session.connector.ResourceConnector;
import org.apache.cocoon.webapps.session.connector.Resource;
import org.apache.cocoon.webapps.session.xml.*;
import org.apache.cocoon.xml.IncludeXMLConsumer;
/**
* This is a simple implementation of the session context.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
* @version CVS $Id: SimpleSessionContext.java,v 1.1 2002/04/17 08:43:57
cziegeler Exp $
*/
public final class SimpleSessionContext
implements SessionContext {
/** Context name */
private String name;
/** The content of the context */
private Document data;
/** The attributes */
private Map attributes = new HashMap();
/** load resource */
private Resource loadResource;
/** save resource */
private Resource saveResource;
// Refactoring of Xpath Functions.
private XPathContext xpathSupport;
private PrefixResolverDefault prefixResolver;
private Map XpathTable;
public SimpleSessionContext()
throws ProcessingException {
data = XMLUtil.createDocument();
data.appendChild(data.createElementNS(null, "context"));
// Refactoring of Xpath Functions.
xpathSupport = null;
prefixResolver = null;
XpathTable = new HashMap();
}
/**
* Get the name of the context
*/
public String getName() {
return this.name;
}
/**
* doXPath
*/
private XObject doXPath(String path)
throws javax.xml.transform.TransformerException {
// If not there - create or else reset().
if (xpathSupport == null) xpathSupport = new XPathContext();
else xpathSupport.reset();
Node namespaceNode = (Node)data;
if (prefixResolver == null) prefixResolver = new
PrefixResolverDefault(
(namespaceNode.getNodeType() == Node.DOCUMENT_NODE) ? ((Document)
namespaceNode).getDocumentElement() : namespaceNode);
// Create the XPath object.
XPath xpath = (XPath)XpathTable.get(path);
if (xpath == null) {
xpath = new XPath(path, null, prefixResolver, XPath.SELECT, null);
XpathTable.put(path,xpath);
}
// Execute the XPath, and have it return the result
int ctxtNode = xpathSupport.getDTMHandleFromNode(data);
return xpath.execute(xpathSupport, ctxtNode, prefixResolver);
}
public void setup(String value, Resource load, Resource save) {
this.name = value;
this.loadResource = load;
this.saveResource = save;
}
public synchronized DocumentFragment getXML(String path)
throws ProcessingException {
DocumentFragment result = null;
NodeList list;
path = this.createPath(path);
try {
String[] pathComponents = XMLUtil.buildPathArray(path);
if (pathComponents == null) {
//list = XMLUtil.selectNodeList(data, path);
list = doXPath(path).nodelist();
} else {
list = XMLUtil.getNodeListFromPath(data, pathComponents);
}
} catch (javax.xml.transform.TransformerException localException) {
throw new ProcessingException("Transforming exception during
selectSingleNode with path: '"+path+"'. Exception: " + localException,
localException);
}
if (list != null && list.getLength() > 0) {
Document doc = XMLUtil.createDocument();
result = doc.createDocumentFragment();
for(int i = 0; i < list.getLength(); i++) {
// the found node is either an attribute or an element
if (list.item(i).getNodeType() == Node.ATTRIBUTE_NODE) {
// if it is an attribute simple create a new text node
with the value of the attribute
result.appendChild(doc.createTextNode(list.item(i).getNodeValue()));
} else {
// now we have an element
// copy all children of this element in the resulting tree
NodeList childs = list.item(i).getChildNodes();
if (childs != null) {
for(int m = 0; m < childs.getLength(); m++) {
result.appendChild(doc.importNode(childs.item(m),
true));
}
}
}
}
}
return result;
}
public synchronized void setXML(String path, DocumentFragment fragment)
throws ProcessingException {
path = this.createPath(path);
Node node = XMLUtil.selectSingleNode(data, path);
if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
// now we have to serialize the fragment to a string and insert
this
Attr attr = (Attr)node;
attr.setNodeValue(XMLUtil.getValueOfNode(fragment));
} else {
// remove old childs
while (node.hasChildNodes() == true) {
node.removeChild(node.getFirstChild());
}
// Insert new childs
NodeList childs = fragment.getChildNodes();
if (childs != null && childs.getLength() > 0) {
for(int i = 0; i < childs.getLength(); i++) {
Node n = data.importNode(childs.item(i), true);
node.appendChild(n);
}
}
}
}
/**
* Append a document fragment at the given path. The implementation of
this
* method is context specific.
* Usually the children of the fragment are appended as new children of
the
* node specified by the path.
* If the path is not existent it is created.
*/
public synchronized void appendXML(String path, DocumentFragment fragment)
throws ProcessingException {
path = this.createPath(path);
Node node = XMLUtil.selectSingleNode(data, path);
if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
Attr attr;
if (node.getNodeValue() != null ||
node.getNodeValue().trim().length() > 0) {
// this is an existing attr, create a new one
attr = node.getOwnerDocument().createAttributeNS(null,
node.getNodeName());
node.getParentNode().appendChild(attr);
} else {
attr = (Attr)node;
}
// now we have to serialize the fragment to a string and insert
this
attr.setNodeValue(XMLUtil.getValueOfNode(fragment));
} else {
// Insert new childs
NodeList childs = fragment.getChildNodes();
if (childs != null && childs.getLength() > 0) {
for(int i = 0; i < childs.getLength(); i++) {
Node n = data.importNode(childs.item(i), true);
node.appendChild(n);
}
}
}
}
/**
* Build path
*/
private String createPath(String path) {
if (path == null) path ="/";
if (path.startsWith("/") == false) path = "/" + path;
path = "context" + path;
if (path.endsWith("/") == true) path = path.substring(0,
path.length() - 1);
return path;
}
/**
* Remove nodes
*/
public synchronized void removeXML(String path)
throws ProcessingException {
NodeList list;
path = this.createPath(path);
try {
String[] pathComponents = XMLUtil.buildPathArray(path);
if (pathComponents == null) {
//list = XMLUtil.selectNodeList(data, path);
list = doXPath(path).nodelist();
} else {
list = XMLUtil.getNodeListFromPath(data, pathComponents);
}
} catch (javax.xml.transform.TransformerException localException) {
list = null;
}
if (list != null && list.getLength() > 0) {
int len = list.getLength();
Node child;
for(int i = 0; i < len; i++) {
child = list.item(len - 1 -i);
child.getParentNode().removeChild(child);
}
}
}
/**
* Get a copy the first node specified by the path.
*/
public synchronized Node getSingleNode(String path)
throws ProcessingException {
Node result = null;
path = this.createPath(path);
try {
result = XMLUtil.getSingleNode(data, path);
if (result != null) result = result.cloneNode(true);
} catch (javax.xml.transform.TransformerException localException) {
throw new ProcessingException("TransformerException: " +
localException, localException);
}
return result;
}
/**
* Get a copy all the nodes specified by the path.
*/
public synchronized NodeList getNodeList(String path)
throws ProcessingException {
NodeList result = null;
path = this.createPath(path);
try {
String[] pathComponents = XMLUtil.buildPathArray(path);
if (pathComponents == null) {
//result = XMLUtil.selectNodeList(data, path);
result = doXPath(path).nodelist();
} else {
result = XMLUtil.getNodeListFromPath(data, pathComponents);
}
// clone list
if (result != null) {
result = new NodeListImpl(result);
}
} catch (javax.xml.transform.TransformerException localException) {
throw new ProcessingException("TransformerException: " +
localException, localException);
}
return result;
}
/**
* Set the value of a node. The node is copied before insertion.
*/
public synchronized void setNode(String path, Node node)
throws ProcessingException {
if (path != null && path.equals("/") == true) {
throw new ProcessingException("Not a valid path for setNode(): "
+ path);
}
path = this.createPath(path);
Node removeNode = XMLUtil.selectSingleNode(data, path);
removeNode.getParentNode().replaceChild(data.importNode(node, true),
removeNode);
}
/**
* Set a context attribute. If value is null the attribute is removed.
*/
public synchronized void setAttribute(String key, Object value) {
if (value == null) {
attributes.remove(key);
} else {
attributes.put(key, value);
}
}
/**
* Get a context attribute. If the attribute is not available return null
*/
public synchronized Object getAttribute(String key) {
return attributes.get(key);
}
/**
* Get a context attribute. If the attribute is not available the
defaultObject is returned
*/
public synchronized Object getAttribute(String key, Object defaultObject)
{
Object value = attributes.get(key);
if (value == null) value = defaultObject;
return value;
}
/**
* Get the value of this node. This is similiar to the xsl:value-of
* function. If the node does not exist, <code>null</code> is returned.
*/
public synchronized String getValueOfNode(String path)
throws ProcessingException {
String value = null;
path = this.createPath(path); // correct path
value = XMLUtil.getValueOf(data, path);
return value;
}
/**
* Set the value of a node.
*/
public synchronized void setValueOfNode(String path, String value)
throws ProcessingException {
path = this.createPath(path); // correct path
Node node = XMLUtil.selectSingleNode(data, path);
if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
Attr attr = (Attr)node;
attr.setNodeValue(value);
} else {
// remove old childs
while (node.hasChildNodes() == true) {
node.removeChild(node.getFirstChild());
}
node.appendChild(node.getOwnerDocument().createTextNode(value));
}
}
/**
* Stream the XML directly to the handler. This streams the contents of
getXML()
* to the given handler without creating a DocumentFragment containing a
copy
* of the data
*/
public synchronized boolean streamXML(String path, ContentHandler
contentHandler,
LexicalHandler lexicalHandler)
throws SAXException, ProcessingException {
NodeList list;
boolean streamed = false;
path = this.createPath(path);
try {
String[] pathComponents = XMLUtil.buildPathArray(path);
if (pathComponents == null) {
//list = XMLUtil.selectNodeList(data, path);
list = doXPath(path).nodelist();
} else {
list = XMLUtil.getNodeListFromPath(data, pathComponents);
}
} catch (javax.xml.transform.TransformerException local) {
throw new ProcessingException("TransformerException: " + local,
local);
}
if (list != null && list.getLength() > 0) {
streamed = true;
for(int i = 0; i < list.getLength(); i++) {
// the found node is either an attribute or an element
if (list.item(i).getNodeType() == Node.ATTRIBUTE_NODE) {
// if it is an attribute simple create a new text node
with the value of the attribute
String value = list.item(i).getNodeValue();
contentHandler.characters(value.toCharArray(), 0,
value.length());
} else {
// now we have an element
// stream all children of this element to the resulting
tree
NodeList childs = list.item(i).getChildNodes();
if (childs != null) {
for(int m = 0; m < childs.getLength(); m++) {
IncludeXMLConsumer.includeNode(childs.item(m),
contentHandler, lexicalHandler);
}
}
}
}
}
return streamed;
}
/**
* Try to load XML into the context.
* If the context does not provide the ability of loading,
* an exception is thrown.
*/
public void loadXML(String path,
SourceParameters parameters,
Map objectModel,
SourceResolver resolver,
ComponentManager manager)
throws SAXException, ProcessingException, IOException {
if (this.loadResource == null) {
throw new ProcessingException("The context " + this.name + " does
not support loading.");
}
ResourceConnector connector = null;
try {
if (parameters != null) {
parameters = (SourceParameters)parameters.clone();
parameters.add(this.loadResource.getResourceParameters());
} else {
parameters = this.loadResource.getResourceParameters();
}
connector =
(ResourceConnector)manager.lookup(ResourceConnector.ROLE);
DocumentFragment df =
connector.loadXML(this.loadResource.getResourceType(), null,
this.loadResource.getResourceIdentifier(), parameters);
if (df != null) this.setXML(path, df);
} catch (ComponentException ce) {
throw new ProcessingException("Unable to lookup the resource
connector.", ce);
} finally {
manager.release( connector );
}
}
/**
* Try to save XML from the context.
* If the context does not provide the ability of saving,
* an exception is thrown.
*/
public void saveXML(String path,
SourceParameters parameters,
Map objectModel,
SourceResolver resolver,
ComponentManager manager)
throws SAXException, ProcessingException, IOException {
if (this.saveResource == null) {
throw new ProcessingException("The context " + this.name + " does
not support saving.");
}
ResourceConnector connector = null;
try {
if (parameters != null) {
parameters = (SourceParameters)parameters.clone();
parameters.add(this.saveResource.getResourceParameters());
} else {
parameters = this.saveResource.getResourceParameters();
}
DocumentFragment frag = this.getXML(path);
if (frag == null) {
// create empty fake document
frag = XMLUtil.createDocument().createDocumentFragment();
}
connector =
(ResourceConnector)manager.lookup(ResourceConnector.ROLE);
connector.saveXML(this.saveResource.getResourceType(), null,
this.saveResource.getResourceIdentifier(),
parameters,
frag);
} catch (ComponentException ce) {
throw new ProcessingException("Unable to lookup the resource
connector.", ce);
} finally {
manager.release( connector );
}
}
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/webapps/session/context/StandardSessionContextProvider.java
Index: StandardSessionContextProvider.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
[EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache
Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.cocoon.webapps.session.context;
import java.util.Map;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.cocoon.webapps.session.SessionConstants;
/**
* Context provider for the temporarily context, the request and the
* response context.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
* @version CVS $Id: StandardSessionContextProvider.java,v 1.1 2002/04/17
08:43:57 cziegeler Exp $
*/
public final class StandardSessionContextProvider
implements SessionContextProvider {
/**
* Get the context
* @param name The name of the context
* @param objectModel The objectModel of the current request.
* @param resolver The source resolver
* @param componentManager manager
* @result The context
* @throws ProcessingException If the context is not available.
*/
public SessionContext getSessionContext(String name,
Map objectModel,
SourceResolver resolver,
ComponentManager manager)
throws ProcessingException {
SessionContext context = null;
if ( name.equals(SessionConstants.TEMPORARY_CONTEXT) ) {
context = new SimpleSessionContext();
context.setup(name, null, null);
} else if ( name.equals(SessionConstants.REQUEST_CONTEXT) ) {
context = new RequestSessionContext();
context.setup(name, null, null);
((RequestSessionContext)context).setup( objectModel, manager );
} else if ( name.equals(SessionConstants.RESPONSE_CONTEXT) ) {
context = new ResponseSessionContext();
context.setup(name, null, null);
((ResponseSessionContext)context).setup( objectModel );
}
return context;
}
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/webapps/session/transformation/AbstractSessionTransformer.java
Index: AbstractSessionTransformer.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
[EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache
Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.cocoon.webapps.session.transformation;
import java.io.*;
import java.util.*;
import org.apache.avalon.excalibur.source.SourceParameters;
import org.apache.avalon.framework.component.ComponentException;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.component.Composable;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.excalibur.pool.Recyclable;
import org.apache.cocoon.components.parser.Parser;
import org.apache.cocoon.environment.Context;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.environment.Response;
import org.apache.cocoon.environment.Session;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.transformation.AbstractSAXTransformer;
import org.apache.cocoon.webapps.session.components.SessionManager;
import org.apache.cocoon.webapps.session.connector.*;
import org.apache.cocoon.xml.IncludeXMLConsumer;
import org.apache.cocoon.xml.XMLConsumer;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
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.ext.LexicalHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
/**
* This class is the basis for all session transformers.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
* @version CVS $Id: AbstractSessionTransformer.java,v 1.1 2002/04/17
08:43:57 cziegeler Exp $
*/
public abstract class AbstractSessionTransformer
extends AbstractSAXTransformer {
private SessionManager sessionManager;
/** The Resource Connector */
private ResourceConnector resourceConnector;
/** The SourceResolver for this request */
/**
* Get the SessionManager component
*/
protected SessionManager getSessionManager()
throws ProcessingException {
if (this.sessionManager == null) {
try {
this.sessionManager =
(SessionManager)this.manager.lookup(SessionManager.ROLE);
} catch (ComponentException ce) {
throw new ProcessingException("Error during lookup of
SessionManager component.", ce);
}
}
return this.sessionManager;
}
/**
* Get the resource connector
*/
protected ResourceConnector getResourceConnector()
throws ProcessingException {
if (this.resourceConnector == null) {
try {
this.resourceConnector =
(ResourceConnector)this.manager.lookup(ResourceConnector.ROLE);
} catch (ComponentException ce) {
throw new ProcessingException("Error during lookup of
resource connector.", ce);
}
}
return this.resourceConnector;
}
/**
* Recycle this component.
*/
public void recycle() {
super.recycle();
this.manager.release(this.resourceConnector);
this.manager.release(this.sessionManager);
this.resourceConnector = null;
this.sessionManager = null;
}
/**
* Get the current session if available or return <code>null</code>.
* @return The Session object or null.
*/
public Session getSession()
throws ProcessingException {
return this.getSessionManager().getSession(false);
}
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/webapps/session/transformation/ConnectTransformer.java
Index: ConnectTransformer.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
[EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache
Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.cocoon.webapps.session.transformation;
import java.io.IOException;
import java.util.Map;
import java.util.Properties;
import org.apache.avalon.excalibur.source.SourceParameters;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.webapps.session.connector.*;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import org.w3c.dom.DocumentFragment;
import javax.xml.transform.OutputKeys;
/**
* This is the connect transformer.
* The class is abstract as the SessionPreTransformer inherits from
* this class.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
* @version CVS $Id: ConnectTransformer.java,v 1.1 2002/04/17 08:43:57
cziegeler Exp $
*/
public abstract class ConnectTransformer
extends AbstractSessionTransformer{
public static final String INCLUDE_XML_ELEMENT = "include";
public static final String CONNECTION_ELEMENT = "connection";
public static final String CTARGET_ELEMENT = "target";
public static final String CCONFIGLIST_ELEMENT = "config";
public static final String CPARAMLIST_ELEMENT = "params";
public static final String CPARAM_ELEMENT = "param";
public static final String CPARAMNAME_ELEMENT = "name";
public static final String CPARAMVALUE_ELEMENT = "value";
private SourceParameters callParams;
private Parameters configParams;
private static final int STATE_OUTSIDE = 0;
private static final int STATE_INCLUDE = 1;
private static final int STATE_CONNECTION= 2;
private static final int STATE_FILE = 3;
private static final int STATE_RESOURCE = 4;
private int state;
/**
* Setup the transformer
*/
public void setupTransforming()
throws ProcessingException, SAXException, IOException {
super.setupTransforming();
this.state = ConnectTransformer.STATE_OUTSIDE;
}
/**
* Recycle the component
*/
public void recycle() {
super.recycle();
this.callParams = null;
this.configParams = null;
}
/**
* This is the real implementation of the startElement event for the
Transformer
* The event is checked for a valid element and the corresponding command
* is executed.
*/
public void startTransformingElement(String uri,
String name,
String raw,
Attributes attr)
throws ProcessingException, IOException, SAXException {
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN startTransformingElement uri=" +
uri +
", name=" + name + ", raw=" + raw + ",
attr=" + attr + ")");
}
// Element: include
if (name.equals(INCLUDE_XML_ELEMENT) == true
&& this.state == STATE_OUTSIDE) {
this.state = ConnectTransformer.STATE_INCLUDE;
String ignoreErrors = attr.getValue("ignoreErrors");
if (ignoreErrors == null || ignoreErrors.length() == 0) {
ignoreErrors = "false";
}
this.stack.push(new Boolean(this.ignoreEmptyCharacters));
this.stack.push(new Boolean(this.ignoreWhitespaces));
this.stack.push(ignoreErrors);
this.ignoreEmptyCharacters = false;
this.ignoreWhitespaces = true;
} else if (name.equals(CONNECTION_ELEMENT) == true
&& this.state == ConnectTransformer.STATE_INCLUDE) {
this.state = ConnectTransformer.STATE_CONNECTION;
// target
} else if (name.equals(CTARGET_ELEMENT) == true
&& this.state == ConnectTransformer.STATE_CONNECTION) {
this.startTextRecording();
// configparameters
} else if (name.equals(CCONFIGLIST_ELEMENT) == true
&& this.state == ConnectTransformer.STATE_CONNECTION) {
stack.push("CONFIGPARAMEND");
// parameters
} else if (name.equals(CPARAMLIST_ELEMENT) == true
&& this.state == ConnectTransformer.STATE_CONNECTION) {
stack.push("PARAMEND");
// parameter
} else if (name.equals(CPARAM_ELEMENT) == true
&& this.state == ConnectTransformer.STATE_CONNECTION) {
// parameter name
} else if (name.equals(CPARAMNAME_ELEMENT) == true
&& this.state == ConnectTransformer.STATE_CONNECTION) {
this.startTextRecording();
// parameter value
} else if (name.equals(CPARAMVALUE_ELEMENT) == true
&& this.state == ConnectTransformer.STATE_CONNECTION) {
Properties format = new Properties();
format.put(OutputKeys.METHOD, "xml");
format.put(OutputKeys.OMIT_XML_DECLARATION, "yes");
this.startSerializedXMLRecording(format);
// unknown
} else {
super.startTransformingElement(uri, name, raw, attr);
}
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END startTransformingElement");
}
}
public void endTransformingElement(String uri,
String name,
String raw)
throws ProcessingException ,IOException, SAXException {
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN endTransformingElement uri=" + uri +
", name=" + name + ", raw=" + raw);
}
if (name.equals(CONNECTION_ELEMENT) == true
&& this.state == ConnectTransformer.STATE_CONNECTION) {
// We should have everything on the stack now
String target = (String)stack.pop();
this.stack.push(target);
this.state = ConnectTransformer.STATE_INCLUDE;
// Element: include
} else if (name.equals(INCLUDE_XML_ELEMENT) == true
&& this.state == STATE_INCLUDE) {
this.state = ConnectTransformer.STATE_OUTSIDE;
final String resource = (String)stack.pop();
final boolean ignoreErrors = ((String)stack.pop()).equals("true");
final Resource resourceObject = new Resource(this.resolver,
resource);
try {
this.getResourceConnector().streamXML(resourceObject.getResourceType(),
configParams,
resourceObject.getResourceIdentifier(), callParams,
this, this);
} catch (ProcessingException sse) {
if (ignoreErrors == false) throw sse;
}
this.ignoreWhitespaces = ((Boolean)stack.pop()).booleanValue();
this.ignoreEmptyCharacters =
((Boolean)stack.pop()).booleanValue();
} else if (name.equals(CTARGET_ELEMENT) == true
&& this.state == ConnectTransformer.STATE_CONNECTION) {
stack.push(this.endTextRecording());
} else if (name.equals(CCONFIGLIST_ELEMENT) == true
&& this.state == ConnectTransformer.STATE_CONNECTION) {
configParams = new Parameters();
// Now get the parameters off the stack
String label = (String)stack.pop();
String value="";
while (!label.equals("CONFIGPARAMEND")) {
value = (String)stack.pop();
configParams.setParameter((String)stack.pop(), value);
label = (String)stack.pop();
}
} else if (name.equals(CPARAMLIST_ELEMENT) == true
&& this.state == ConnectTransformer.STATE_CONNECTION) {
callParams = new SourceParameters();
// Now get the parameters off the stack
String label = (String)stack.pop();
String value="";
while (!label.equals("PARAMEND")) {
value = (String)stack.pop();
callParams.setParameter((String)stack.pop(), value);
label = (String)stack.pop();
}
} else if (name.equals(CPARAM_ELEMENT) == true
&& this.state == ConnectTransformer.STATE_CONNECTION) {
} else if (name.equals(CPARAMNAME_ELEMENT) == true
&& this.state == ConnectTransformer.STATE_CONNECTION) {
stack.push(this.endTextRecording());
// parameter value
} else if (name.equals(CPARAMVALUE_ELEMENT) == true
&& this.state == ConnectTransformer.STATE_CONNECTION) {
stack.push(this.endSerializedXMLRecording());
stack.push("xml");
} else {
super.endTransformingElement(uri, name, raw);
}
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END endTransformingElement");
}
}
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/webapps/session/transformation/SessionPostTransformer.java
Index: SessionPostTransformer.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
[EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache
Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.cocoon.webapps.session.transformation;
import java.io.IOException;
import java.util.Map;
import org.apache.avalon.excalibur.source.SourceParameters;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.webapps.session.SessionConstants;
import org.apache.cocoon.webapps.session.connector.*;
import org.apache.cocoon.webapps.session.xml.XMLUtil;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import org.w3c.dom.DocumentFragment;
/**
* This is the session post transformer. It does all the setting and
* destroying. Thus it should be the last transformer (before the xsl) in
* the pipeline.
* For performance and simplicity reasons this transformer inherits from
* the SessionPreTransformer, although this is not needed (But then the
* implementation of the SessionTransformer would be very unperformant.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
* @version CVS $Id: SessionPostTransformer.java,v 1.1 2002/04/17 08:43:57
cziegeler Exp $
*/
public class SessionPostTransformer
extends SessionPreTransformer {
public static final String DELETECONTEXT_ELEMENT = "deletecontext";
public static final String DELETECONTEXT_NAME_ATTRIBUTE = "name";
public static final String SETXML_ELEMENT = "setxml";
public static final String SETXML_CONTEXT_ATTRIBUTE = "context";
public static final String SETXML_PATH_ATTRIBUTE = "path";
public static final String APPENDXML_ELEMENT = "appendxml";
public static final String APPENDXML_CONTEXT_ATTRIBUTE = "context";
public static final String APPENDXML_PATH_ATTRIBUTE = "path";
public static final String REMOVEXML_ELEMENT = "removexml";
public static final String REMOVEXML_CONTEXT_ATTRIBUTE = "context";
public static final String REMOVEXML_PATH_ATTRIBUTE = "path";
public static final String MERGEXML_ELEMENT = "mergexml";
public static final String MERGEXML_CONTEXT_ATTRIBUTE = "context";
public static final String MERGEXML_PATH_ATTRIBUTE = "path";
public static final String SAVECONTEXT_ELEMENT = "savexml";
public static final String SAVECONTEXT_CONTEXT_ATTRIBUTE = "context";
public static final String SAVECONTEXT_PATH_ATTRIBUTE = "path"; //
optional
public static final String INPUTXML_ELEMENT = "inputxml";
public static final String INPUTXML_CONTEXT_ATTRIBUTE = "context";
public static final String INPUTXML_PATH_ATTRIBUTE = "path";
public static final String INPUTXML_NAME_ATTRIBUTE = "name";
public static final String INPUTXML_TYPE_ATTRIBUTE = "type"; // optional
/** The form element */
public static final String FORM_ELEMENT = "form";
/** The form action element */
public static final String FORM_ACTION_ELEMENT = "action";
/** The form content element */
public static final String FORM_CONTENT_ELEMENT = "content";
/** State: no element parsed */
private static final int STATE_OUTSIDE = 0;
/** State: form element */
private static final int STATE_FORM = 1;
/** The current state */
private int state;
/** The current form name */
private String formName;
/** The unique form number */
private static int currentFormNumber = 0;
public void setupTransforming()
throws ProcessingException, SAXException, IOException {
super.setupTransforming();
this.state = STATE_OUTSIDE;
this.formName = null;
}
/**
* This is the real implementation of the startElement event
* for the transformer
* The event is checked for a valid element and the corresponding command
* is executed.
*/
public void startTransformingElement(String uri,
String name,
String raw,
Attributes attr)
throws ProcessingException, IOException, SAXException {
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN startTransformingElement uri=" +
uri +
", name=" + name + ", raw=" + raw + ",
attr=" + attr);
}
if (name.equals(DELETECONTEXT_ELEMENT) == true) {
this.getSessionManager().deleteContext(attr.getValue(DELETECONTEXT_NAME_ATTRIBUTE));
} else if (name.equals(SETXML_ELEMENT) == true) {
this.startRecording();
stack.push(attr.getValue(SETXML_CONTEXT_ATTRIBUTE));
stack.push(attr.getValue(SETXML_PATH_ATTRIBUTE));
// Element: mergexml
} else if (name.equals(MERGEXML_ELEMENT) == true) {
this.startRecording();
stack.push(attr.getValue(MERGEXML_CONTEXT_ATTRIBUTE));
stack.push(attr.getValue(MERGEXML_PATH_ATTRIBUTE));
// Element: appendxml
} else if (name.equals(APPENDXML_ELEMENT) == true) {
this.startRecording();
stack.push(attr.getValue(APPENDXML_CONTEXT_ATTRIBUTE));
stack.push(attr.getValue(APPENDXML_PATH_ATTRIBUTE));
// Element: removexml
} else if (name.equals(REMOVEXML_ELEMENT) == true) {
this.startTextRecording();
stack.push(attr.getValue(REMOVEXML_CONTEXT_ATTRIBUTE));
stack.push(attr.getValue(REMOVEXML_PATH_ATTRIBUTE));
} else if (name.equals(SAVECONTEXT_ELEMENT) == true) {
this.startParametersRecording();
stack.push(attr.getValue(SAVECONTEXT_CONTEXT_ATTRIBUTE));
if (attr.getValue(SAVECONTEXT_PATH_ATTRIBUTE) != null) {
stack.push(attr.getValue(SAVECONTEXT_PATH_ATTRIBUTE));
} else {
stack.push("/");
}
// Element: inputxml
} else if (name.equals(INPUTXML_ELEMENT) == true) {
stack.push(attr.getValue(INPUTXML_CONTEXT_ATTRIBUTE));
String fieldname = attr.getValue(INPUTXML_NAME_ATTRIBUTE);
stack.push(fieldname);
stack.push(attr.getValue(INPUTXML_PATH_ATTRIBUTE));
AttributesImpl newattr = new AttributesImpl();
newattr.addAttribute("", INPUTXML_NAME_ATTRIBUTE,
INPUTXML_NAME_ATTRIBUTE, "CDATA", fieldname);
if (attr.getValue(INPUTXML_TYPE_ATTRIBUTE) != null) {
newattr.addAttribute("",
INPUTXML_TYPE_ATTRIBUTE,
INPUTXML_TYPE_ATTRIBUTE,
"CDATA",
attr.getValue(INPUTXML_TYPE_ATTRIBUTE));
}
super.startTransformingElement("", name, name, newattr); //
remove namespace
this.startRecording();
// Element form
} else if (name.equals(FORM_ELEMENT) == true
&& this.state == STATE_OUTSIDE) {
String formName = attr.getValue("name");
if (formName == null) {
throw new ProcessingException("The name attribute of the form
element is required.");
}
this.stack.push(new Integer(this.state));
this.state = STATE_FORM;
this.stack.push(new AttributesImpl(attr));
// Element form action
} else if (name.equals(FORM_ACTION_ELEMENT) == true
&& this.state == STATE_FORM) {
this.startTextRecording();
// Element form content
} else if (name.equals(FORM_CONTENT_ELEMENT) == true
&& this.state == STATE_FORM) {
// ignore this
} else {
super.startTransformingElement(uri, name, raw, attr);
}
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END startTransformingElement");
}
}
public void endTransformingElement(String uri,
String name,
String raw)
throws ProcessingException ,IOException, SAXException {
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN endTransformingElement uri=" + uri
+ ", name=" + name + ", raw=" + raw);
}
if (name.equals(DELETECONTEXT_ELEMENT) == true) {
// do nothing, the context was destroyed on the startElement event
// Element: setxml
} else if (name.equals(SETXML_ELEMENT) == true) {
String path = (String)stack.pop();
String contextName = (String)stack.pop();
this.getSessionManager().setContextFragment(contextName, path,
this.endRecording());
// Element: mergexml
} else if (name.equals(MERGEXML_ELEMENT) == true) {
String path = (String)stack.pop();
String contextName = (String)stack.pop();
this.getSessionManager().mergeContextFragment(contextName, path,
this.endRecording());
// Element: appendxml
} else if (name.equals(APPENDXML_ELEMENT) == true) {
String path = (String)stack.pop();
String contextName = (String)stack.pop();
this.getSessionManager().appendContextFragment(contextName, path,
this.endRecording());
// Element: removexml
} else if (name.equals(REMOVEXML_ELEMENT) == true) {
String path = (String)stack.pop();
String contextName = (String)stack.pop();
String text = this.endTextRecording(); //this is ignored
this.getSessionManager().removeContextFragment(contextName, path);
// Element: savexml
} else if (name.equals(SAVECONTEXT_ELEMENT) == true) {
String path = (String)stack.pop();
String contextName = (String)stack.pop();
SourceParameters pars =
this.endParametersRecording((SourceParameters)null);
pars.setSingleParameterValue("contextname", contextName);
pars.setSingleParameterValue("path", path);
this.getSessionManager().getContext(contextName).saveXML(path,
pars,
this.objectModel,
this.resolver,
this.manager);
// Element: inputxml
} else if (name.equals(INPUTXML_ELEMENT) == true) {
String path = (String)this.stack.pop();
String fieldname = (String)this.stack.pop();
String contextname = (String)this.stack.pop();
DocumentFragment defaultFragment = this.endRecording();
if (this.formName == null) {
throw new ProcessingException("The inputxml must be contained
inside a form.");
}
DocumentFragment value =
this.getSessionManager().registerInputField(contextname, path, fieldname,
formName);
if (value == null) value = defaultFragment;
this.sendEvents(value);
super.endTransformingElement("", name, name);
// Element form
} else if (name.equals(FORM_ELEMENT) == true
&& this.state == STATE_FORM) {
this.state = ((Integer)this.stack.pop()).intValue();
this.sendEndElementEvent("form");
this.formName = null;
// Element form action
} else if (name.equals(FORM_ACTION_ELEMENT) == true
&& this.state == STATE_FORM) {
String action = this.endTextRecording();
AttributesImpl a = (AttributesImpl)this.stack.pop();
// append a unique number to the form
synchronized (this.getClass()) {
this.formName = a.getValue("name") + '_' + currentFormNumber;
currentFormNumber++;
if (currentFormNumber > 99999) currentFormNumber = 0;
}
boolean hasPars = (action.indexOf("?") != -1);
action = this.response.encodeURL(action + (hasPars ? '&' : '?') +
SessionConstants.SESSION_FORM_PARAMETER+'='+this.formName);
a.addAttribute("", "action", "action", "CDATA", action);
if (a.getValue("method") == null) {
a.addAttribute("", "method", "method", "CDATA", "POST");
}
this.sendStartElementEvent("form", a);
// Element form content
} else if (name.equals(FORM_CONTENT_ELEMENT) == true
&& this.state == STATE_FORM) {
// ignore this
} else {
super.endTransformingElement(uri, name, raw);
}
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END endTransformingElement");
}
}
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/webapps/session/transformation/SessionPreTransformer.java
Index: SessionPreTransformer.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
[EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache
Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.cocoon.webapps.session.transformation;
import java.io.IOException;
import java.util.Map;
import org.apache.avalon.excalibur.source.SourceParameters;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.environment.SourceResolver;
import org.apache.cocoon.webapps.session.SessionConstants;
import org.apache.cocoon.webapps.session.connector.*;
import org.apache.cocoon.xml.XMLUtils;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import org.w3c.dom.DocumentFragment;
/**
* This is the session pre transformer. It does all the getting
* and creation commands. This transformer should be the first in the
* pipeline.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
* @version CVS $Id: SessionPreTransformer.java,v 1.1 2002/04/17 08:43:57
cziegeler Exp $
*/
public class SessionPreTransformer
extends ConnectTransformer {
/*
* The XML commands
*/
public static final String CREATECONTEXT_ELEMENT = "createcontext";
public static final String CREATECONTEXT_NAME_ATTRIBUTE = "name";
public static final String CREATECONTEXT_SAVE_ATTRIBUTE = "save"; //
optional
public static final String CREATECONTEXT_LOAD_ATTRIBUTE = "load"; //
optional
public static final String GETXML_ELEMENT = "getxml";
public static final String GETXML_CONTEXT_ATTRIBUTE = "context";
public static final String GETXML_PATH_ATTRIBUTE = "path";
public static final String LOADCONTEXT_ELEMENT = "loadxml";
public static final String LOADCONTEXT_CONTEXT_ATTRIBUTE = "context";
public static final String LOADCONTEXT_PATH_ATTRIBUTE = "path"; //
optional
/** The contexturl element.
*/
public static final String CONTEXT_URL_ELEMENT = "contexturl";
/** The link element */
public static final String LINK_ELEMENT = "link";
/** The name attribute of the link element. */
public static final String LINK_NAME_ATTRIBUTE = "name";
/** The name attribute of the link element. */
public static final String LINK_TARGET_ATTRIBUTE = "target";
/** The name attribute of the link element. */
public static final String LINK_MEDIUM_ATTRIBUTE = "medium";
/** The default link pipeline */
protected static String linkResource;
/** The current link pipeline */
protected Resource currentLinkResource;
/** Are we inside a getxml? */
protected int processingGetXML;
public SessionPreTransformer() {
this.namespaceURI = SessionConstants.SESSION_NAMESPACE_URI;
}
/**
* Configure
*/
public void configure(Configuration conf)
throws ConfigurationException {
super.configure(conf);
Configuration lnkResConf = conf.getChild("link-resource", false);
if (lnkResConf != null) {
linkResource = lnkResConf.getAttribute("uri");
}
}
/**
* Setup the next round.
* The instance variables are initialised.
* @param resolver The current SourceResolver
* @param objectModel The objectModel of the environment.
* @param src The value of the src attribute in the sitemap.
* @param par The parameters from the sitemap.
*/
public void setup(SourceResolver resolver,
Map objectModel,
String src,
Parameters par)
throws ProcessingException,
SAXException,
IOException {
super.setup(resolver, objectModel, src, par);
this.processingGetXML = 0;
final String uri = par.getParameter("link-resource-uri",
this.linkResource);
if ( uri != null ) {
this.currentLinkResource = new Resource(resolver,
par.getParameter("link-resource-uri", this.linkResource));
} else {
this.currentLinkResource = null;
}
}
/**
* Process the SAX event.
* The namespace of the event is checked. If it is the defined namespace
* for this transformer the endTransformingElement() hook is called.
*/
public void endElement(String uri, String name, String raw) throws
SAXException {
super.endElement(uri, name, raw);
if (uri != null
&& namespaceURI != null
&& uri.equals(namespaceURI) == true
&& this.processingGetXML > 0
&& name.equals(GETXML_ELEMENT) == true) {
this.processingGetXML--;
this.ignoreEventsCount--;
this.ignoreHooksCount--;
}
}
/**
* Process the SAX event.
* The namespace of the event is checked. If it is the defined namespace
* for this transformer the endTransformingElement() hook is called.
*/
public void startElement(String uri,
String name,
String raw,
Attributes attr)
throws SAXException {
if (uri != null
&& namespaceURI != null
&& uri.equals(namespaceURI) == true
&& this.processingGetXML > 0
&& name.equals(GETXML_ELEMENT) == true) {
this.processingGetXML++;
this.ignoreEventsCount++;
this.ignoreHooksCount++;
}
super.startElement(uri, name, raw, attr);
}
/**
* This is the real implementation of the startElement event for the
transformer
* The event is checked for a valid element and the corresponding command
* is executed.
*/
public void startTransformingElement(String uri,
String name,
String raw,
Attributes attr)
throws ProcessingException, IOException, SAXException {
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN startTransformingElement uri=" +
uri +
", name=" + name +
", raw=" + raw +
", attr=" + attr);
}
if (name.equals(CREATECONTEXT_ELEMENT) == true) {
this.getSessionManager().createContext(attr.getValue(CREATECONTEXT_NAME_ATTRIBUTE),
attr.getValue(CREATECONTEXT_LOAD_ATTRIBUTE),
attr.getValue(CREATECONTEXT_SAVE_ATTRIBUTE));
} else if (name.equals(GETXML_ELEMENT) == true) {
final String path = attr.getValue(GETXML_PATH_ATTRIBUTE);
final String contextName =
attr.getValue(GETXML_CONTEXT_ATTRIBUTE);
if (this.getSessionManager().streamContextFragment(contextName,
path,
this) == true) {
this.ignoreEventsCount++;
this.ignoreHooksCount++;
this.processingGetXML++;
}
} else if (name.equals(LOADCONTEXT_ELEMENT) == true) {
this.startParametersRecording();
stack.push(attr.getValue(LOADCONTEXT_CONTEXT_ATTRIBUTE));
if (attr.getValue(LOADCONTEXT_PATH_ATTRIBUTE) != null) {
stack.push(attr.getValue(LOADCONTEXT_PATH_ATTRIBUTE));
} else {
stack.push("/");
}
// Element context url
} else if (name.equals(SessionPreTransformer.CONTEXT_URL_ELEMENT) ==
true) {
this.ignoreEventsCount++;
// Element link
} else if (name.equals(LINK_ELEMENT) == true) {
String linkName = attr.getValue(LINK_NAME_ATTRIBUTE);
String target = attr.getValue(LINK_TARGET_ATTRIBUTE);
String medium = attr.getValue(LINK_MEDIUM_ATTRIBUTE);
this.stack.push(linkName);
this.stack.push("LINK");
if (target != null) {
this.stack.push(target);
this.stack.push("TARGET");
}
if (medium != null) {
this.stack.push(medium);
this.stack.push("MEDIUM");
}
this.startSerializedXMLRecording(XMLUtils.defaultSerializeToXMLFormat(true));
// DEFAULT
} else {
super.startTransformingElement(uri, name, raw, attr);
}
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END startTransformingElement");
}
}
public void endTransformingElement(String uri,
String name,
String raw)
throws ProcessingException ,IOException, SAXException {
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("BEGIN endTransformingElement uri=" + uri
+ ", name=" + name + ", raw=" + raw);
}
if (name.equals(CREATECONTEXT_ELEMENT) == true) {
// do nothing, the context was created on the startElement event
} else if (name.equals(GETXML_ELEMENT) == true) {
// do nothing
// Element: loadxml
} else if (name.equals(LOADCONTEXT_ELEMENT) == true) {
String path = (String)stack.pop();
String contextName = (String)stack.pop();
SourceParameters pars =
this.endParametersRecording((SourceParameters)null);
pars.setSingleParameterValue("contextname", contextName);
pars.setSingleParameterValue("path", path);
DocumentFragment frag = null;
this.getSessionManager().getContext(contextName).loadXML(path,
pars,
this.objectModel,
this.resolver,
this.manager);
// Element context url
} else if (name.equals(SessionPreTransformer.CONTEXT_URL_ELEMENT) ==
true) {
this.ignoreEventsCount--;
String contextUrl = this.request.getScheme() + "://" +
this.request.getServerName() + ":" +
this.request.getServerPort() +
this.request.getContextPath();
this.sendTextEvent(contextUrl);
// Element link
} else if (name.equals(LINK_ELEMENT) == true) {
String linkName = null;
String target = null;
String medium = null;
String text = this.endSerializedXMLRecording();
String element;
do {
element = (String)this.stack.pop();
if (element.equals("LINK") == true) {
linkName = (String)this.stack.pop();
} else if (element.equals("TARGET") == true) {
target = (String)this.stack.pop();
} else if (element.equals("MEDIUM") == true) {
medium = (String)this.stack.pop();
}
} while (element.equals("LINK") == false);
if (this.currentLinkResource != null) {
SourceParameters pars = new SourceParameters();
pars.setParameter("name", linkName);
if (target != null) {
pars.setParameter("target", target);
}
if (medium != null) {
pars.setParameter("medium", medium);
}
pars.setParameter("text", text);
this.getResourceConnector().streamXML(this.currentLinkResource.getResourceType(),
null,
this.currentLinkResource.getResourceIdentifier(),
pars,
this.contentHandler,
this.lexicalHandler);
} else {
// medium is ignored here
AttributesImpl attrImp = new AttributesImpl();
attrImp.addAttribute("", "href", "href", "CDATA",
this.response.encodeURL(name));
if (target != null) {
attrImp.addAttribute("", "target", "target", "CDATA",
target);
}
this.sendStartElementEvent("a", attrImp);
this.sendTextEvent(text);
this.sendEndElementEvent("a");
}
// DEFAULT
} else {
super.endTransformingElement(uri, name, raw);
}
if (this.getLogger().isDebugEnabled() == true) {
this.getLogger().debug("END endTransformingElement");
}
}
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/webapps/session/transformation/SessionTransformer.java
Index: SessionTransformer.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
[EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache
Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.cocoon.webapps.session.transformation;
/**
* This is the session transformer which is only for compatibility.
* It inherits from the ConnectTransformer which inherits from
* the SessionPostTransformer whicb inherits from the SessionPreTransformer.
* So those three do all the work
*
* @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
* @version CVS $Id: SessionTransformer.java,v 1.1 2002/04/17 08:43:57
cziegeler Exp $
*/
public class SessionTransformer
extends SessionPostTransformer {
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/webapps/session/xml/NodeListImpl.java
Index: NodeListImpl.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
[EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache
Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.cocoon.webapps.session.xml;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* Implementation of the <code>NodeList</code> interface.<P>
*
* @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
* @version CVS $Id: NodeListImpl.java,v 1.1 2002/04/17 08:43:59 cziegeler
Exp $
*/
public class NodeListImpl implements NodeList {
private Node[] nodelist;
/**
* Construct a NodeList by copying.
*/
public NodeListImpl(NodeList list) {
if (list == null || list.getLength() == 0) {
nodelist = null;
} else {
nodelist = new Node[list.getLength()];
for(int i = 0; i < list.getLength(); i++) {
nodelist[i] = list.item(i).cloneNode(true);
}
}
}
/**
* Constructor
*/
public NodeListImpl(Node[] nodes) {
this.nodelist = nodes;
}
/**
* Constructor
*/
public NodeListImpl() {}
/**
* Construct a NodeList by copying.
*/
public NodeListImpl(DocumentFragment fragment, String rootName) {
if (fragment != null) {
Element root = fragment.getOwnerDocument().createElementNS(null,
rootName);
Node current;
while (fragment.hasChildNodes() == true) {
current = fragment.getFirstChild();
fragment.removeChild(current);
root.appendChild(current);
}
nodelist = new Node[1];
nodelist[0] = root;
}
}
/**
* Add a node to list
*/
public void addNode(Node node) {
if (this.nodelist == null) {
this.nodelist = new Node[1];
this.nodelist[0] = node;
} else {
Node[] copy = new Node[this.nodelist.length+1];
System.arraycopy(this.nodelist, 0, copy, 0, this.nodelist.length);
copy[copy.length-1] = node;
this.nodelist = copy;
}
}
/**
* Returns the <code>index</code> th item in the collection. If
* <code>index</code> is greater than or equal to the number of nodes in
* the list, this returns <code>null</code> .
* @param index Index into the collection.
* @return The node at the <code>index</code> th position in the
* <code>NodeList</code> , or <code>null</code> if that is not a valid
* index.
*/
public Node item(int index) {
if (nodelist == null || index >= nodelist.length) {
return null;
} else {
return nodelist[index];
}
}
/**
* The number of nodes in the list. The range of valid child node indices
* is 0 to <code>length-1</code> inclusive.
*/
public int getLength() {
return (nodelist == null ? 0 : nodelist.length);
}
}
1.1
xml-cocoon2/src/java/org/apache/cocoon/webapps/session/xml/XMLUtil.java
Index: XMLUtil.java
===================================================================
/*
============================================================================
The Apache Software License, Version 1.1
============================================================================
Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without modifica-
tion, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The end-user documentation included with the redistribution, if any, must
include the following acknowledgment: "This product includes software
developed by the Apache Software Foundation (http://www.apache.org/)."
Alternately, this acknowledgment may appear in the software itself, if
and wherever such third-party acknowledgments normally appear.
4. The names "Apache Cocoon" and "Apache Software Foundation" must not be
used to endorse or promote products derived from this software without
prior written permission. For written permission, please contact
[EMAIL PROTECTED]
5. Products derived from this software may not be called "Apache", nor may
"Apache" appear in their name, without prior written permission of the
Apache Software Foundation.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This software consists of voluntary contributions made by many individuals
on behalf of the Apache Software Foundation and was originally created by
Stefano Mazzocchi <[EMAIL PROTECTED]>. For more information on the Apache
Software Foundation, please see <http://www.apache.org/>.
*/
package org.apache.cocoon.webapps.session.xml;
import java.io.*;
import java.util.Properties;
import org.apache.avalon.excalibur.xml.Parser;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.xml.dom.DOMBuilder;
import org.apache.avalon.excalibur.source.SourceParameters;
import org.apache.xpath.XPathAPI;
import org.w3c.dom.*;
import org.w3c.dom.traversal.NodeIterator;
import org.xml.sax.ContentHandler;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.helpers.AttributesImpl;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.dom.DOMSource;
import org.apache.cocoon.xml.IncludeXMLConsumer;
/**
* This class is an utitity class for miscellanous XML functions, like
creating
* DOM documents, searching nodes via XPath and changing nodes using XPath.
*
* This class should be separated into several other ones. The XPath support
should
* go to the XPath component etc. So this class will not be supported
anymore...
*
* @deprecated Do not use this class! We will provide a better solution for
most methods soon.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Carsten Ziegeler</a>
* @version CVS $Id: XMLUtil.java,v 1.1 2002/04/17 08:43:59 cziegeler Exp $
*/
public final class XMLUtil {
/*
* As these methods are invoked often they do not trace anything for
* performances reasons. Also they don't follow the guidelines
* for the same reason.
*/
/**
* Return the <CODE>Node</CODE> from the DOM Node <CODE>rootNode</CODE>
* using the XPath expression <CODE>path</CODE>.
* If the node does not exist, it is created and then returned.
* This is a very simple method for creating new nodes. If the
* XPath contains selectors ([,,,]) or "*" it is of course not
* possible to create the new node. So if you use such XPaths
* the node must exist beforehand.
* An simple exception is if the expression contains attribute
* test to values (e.g. [EMAIL PROTECTED] = 'du' and @number = 'you'],
* the attributes with the given values are added. The attributes
* must be separated with 'and'.
* Another problem are namespaces: XPath requires sometimes selectors for
* namespaces, e.g. : /*[namespace-uri()="uri" and local-name()="name"]
* Creating such a node with a namespace is not possible right now as we
use
* a very simple XPath parser which is not able to parse all kinds of
selectors
* correctly.
*
* @param rootNode The node to start the search.
* @param path XPath expression for searching the node.
* @return The node specified by the path.
* @throws ProcessingException If no path is specified or the XPath
engine fails.
*/
public static Node selectSingleNode(Node rootNode, String path)
throws ProcessingException {
// Now we have to parse the string
// First test: path? rootNode?
if (path == null) {
throw new ProcessingException("XPath is required.");
}
if (rootNode == null) return rootNode;
if (path.length() == 0 || path.equals("/") == true) return rootNode;
// now the first "quick" test is if the node exists using the
// full XPathAPI
try {
Node testNode = XMLUtil.getSingleNode(rootNode, path);
if (testNode != null) return testNode;
} catch (javax.xml.transform.TransformerException local) {
throw new ProcessingException("Transforming exception during
selectSingleNode with path: '"+path+"'. Exception: " + local, local);
}
if (path.startsWith("/") == true) path = path.substring(1); // remove
leading "/"
if (path.endsWith("/") == true) { // remove ending "/" for root node
path = path.substring(0, path.length() - 1);
}
// now step through the nodes!
Node parent = rootNode;
int pos;
int posSelector;
do {
pos = path.indexOf("/"); // get next separator
posSelector = path.indexOf("[");
if (posSelector != -1 && posSelector < pos) {
posSelector = path.indexOf("]");
pos = path.indexOf("/", posSelector);
}
String nodeName;
boolean isAttribute = false;
if (pos != -1) { // found separator
nodeName = path.substring(0, pos); // string until "/"
path = path.substring(pos+1); // rest of string after "/"
} else {
nodeName = path;
}
// test for attribute spec
if (nodeName.startsWith("@") == true) {
isAttribute = true;
}
Node singleNode;
try {
singleNode = XMLUtil.getSingleNode(parent, nodeName);
} catch (javax.xml.transform.TransformerException localException)
{
throw new ProcessingException("XPathUtil.selectSingleNode: "
+ localException.getMessage(), localException);
}
// create node if necessary
if (singleNode == null) {
Node newNode;
// delete XPath selectors
int posSelect = nodeName.indexOf("[");
String XPathExp = null;
if (posSelect != -1) {
XPathExp = nodeName.substring(posSelect+1,
nodeName.length()-1);
nodeName = nodeName.substring(0, posSelect);
}
if (isAttribute == true) {
try {
newNode =
XMLUtil.getOwnerDocument(rootNode).createAttributeNS(null, nodeName);
} catch (DOMException local) {
throw new ProcessingException("Unable to create new
DOM node: '"+nodeName+"'.", local);
}
} else {
try {
newNode =
XMLUtil.getOwnerDocument(rootNode).createElementNS(null, nodeName);
} catch (DOMException local) {
throw new ProcessingException("Unable to create new
DOM node: '"+nodeName+"'.", local);
}
if (XPathExp != null) {
java.util.List attrValuePairs = new
java.util.ArrayList(4);
boolean noError = true;
String attr;
String value;
// scan for attributes
java.util.StringTokenizer tokenizer = new
java.util.StringTokenizer(XPathExp, "= ");
while (tokenizer.hasMoreTokens() == true) {
attr = tokenizer.nextToken();
if (attr.startsWith("@") == true) {
if (tokenizer.hasMoreTokens() == true) {
value = tokenizer.nextToken();
if (value.startsWith("'") &&
value.endsWith("'")) value = value.substring(1, value.length()-1);
if (value.startsWith("\"") &&
value.endsWith("\"")) value = value.substring(1, value.length()-1);
attrValuePairs.add(attr.substring(1));
attrValuePairs.add(value);
} else {
noError = false;
}
} else if (attr.trim().equals("and") == false) {
noError = false;
}
}
if (noError == true) {
for(int l=0;l<attrValuePairs.size();l=l+2) {
((Element)newNode).setAttributeNS(null,
(String)attrValuePairs.get(l),
(String)attrValuePairs.get(l+1));
}
}
}
}
parent.appendChild(newNode);
parent = newNode;
} else {
parent = singleNode;
}
} while (pos != -1);
return parent;
}
/**
* Get the owner of the DOM document belonging to the node.
* This works even if the node is the document itself.
*
* @param node The node.
* @return The corresponding document.
*/
public static Document getOwnerDocument(Node node) {
if (node.getNodeType() == Node.DOCUMENT_NODE) {
return (Document)node;
} else {
return node.getOwnerDocument();
}
}
/**
* Get the value of the node specified by the XPath.
* This works similar to xsl:value-of. If the node does not exist
<CODE>null</CODE>
* is returned.
*
* @param root The node to start the search.
* @param path XPath search expression.
* @return The value of the node or <CODE>null</CODE>
*/
public static String getValueOf(Node root, String path)
throws ProcessingException {
if (path == null) {
throw new ProcessingException("Not a valid XPath: " + path);
}
if (root == null) return null;
if (path.startsWith("/") == true) path = path.substring(1); // remove
leading "/"
if (path.endsWith("/") == true) { // remove ending "/" for root node
path = path.substring(0, path.length() - 1);
}
try {
Node node = XMLUtil.getSingleNode(root, path);
if (node != null) {
return XMLUtil.getValueOfNode(node);
}
} catch (javax.xml.transform.TransformerException localException) {
throw new ProcessingException("XPathUtil.selectSingleNode: " +
localException.getMessage(), localException);
}
return null;
}
/**
* Get the value of the node specified by the XPath.
* This works similar to xsl:value-of. If the node is not found
* the <CODE>defaultValue</CODE> is returned.
*
* @param root The node to start the search.
* @param path XPath search expression.
* @param defaultValue The default value if the node does not exist.
* @return The value of the node or <CODE>defaultValue</CODE>
*/
public static String getValueOf(Node root,
String path,
String defaultValue)
throws ProcessingException {
String value = getValueOf(root, path);
if (value == null) value = defaultValue;
return value;
}
/**
* Get the boolean value of the node specified by the XPath.
* This works similar to xsl:value-of. If the node exists and has a value
* this value is converted to a boolean, e.g. "true" or "false" as value
* will result into the corresponding boolean values.
*
* @param root The node to start the search.
* @param path XPath search expression.
* @return The boolean value of the node.
* @throws ProcessingException If the node is not found.
*/
public static boolean getValueAsBooleanOf(Node root, String path)
throws ProcessingException {
String value = XMLUtil.getValueOf(root, path);
if (value == null) {
throw new ProcessingException("No such node: " + path);
}
return Boolean.valueOf(value).booleanValue();
}
/**
* Get the boolean value of the node specified by the XPath.
* This works similar to xsl:value-of. If the node exists and has a value
* this value is converted to a boolean, e.g. "true" or "false" as value
* will result into the corresponding boolean values.
* If the node does not exist, the <CODE>defaultValue</CODE> is returned.
*
* @param root The node to start the search.
* @param path XPath search expression.
* @param defaultValue Default boolean value.
* @return The value of the node or <CODE>defaultValue</CODE>
*/
public static boolean getValueAsBooleanOf(Node root,
String path,
boolean defaultValue)
throws ProcessingException {
String value = XMLUtil.getValueOf(root, path);
if (value == null) {
return defaultValue;
}
return Boolean.valueOf(value).booleanValue();
}
/**
* Get the value of the DOM node.
* The value of a node is the content of the first text node.
* If the node has no text nodes, <code>null</code> is returned.
*/
public static String getValueOfNode(Node node) {
if (node == null) return null;
if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
return node.getNodeValue();
} else {
String value = null;
node.normalize();
NodeList childs = node.getChildNodes();
int i, l;
i = 0;
l = childs.getLength();
while (i < l && value == null) {
if (childs.item(i).getNodeType() == Node.TEXT_NODE)
value = childs.item(i).getNodeValue().trim();
else
i++;
}
return value;
}
}
/**
* Get the value of the node.
* The value of the node is the content of the first text node.
* If the node has no text nodes the <CODE>defaultValue</CODE> is
* returned.
*/
public static String getValueOfNode(Node node, String defaultValue) {
String value = getValueOfNode(node);
if (value == null) value = defaultValue;
return value;
}
/**
* Set the value of the DOM node.
* All current children of the node are removed and a new text node
* with the value is appended.
*/
public static void setValueOfNode(Node node, String value) {
if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
node.setNodeValue(value);
} else {
while (node.hasChildNodes() == true) {
node.removeChild(node.getFirstChild());
}
node.appendChild(node.getOwnerDocument().createTextNode(value));
}
}
/** XML definition for a document */
private static final String XML_DEFINITION = "<?xml version=\"1.0\"
encoding=\"ISO-8859-1\"?>";
private static final String XML_ROOT_DEFINITION = XML_DEFINITION +
"<root>";
/**
* Get a document fragment from a <code>Reader</code>.
* The reader must provide valid XML, but it is allowed that the XML
* has more than one root node. This xml is parsed by the
* specified parser instance and a DOM DocumentFragment is created.
*/
public static DocumentFragment getDocumentFragment(Parser parser,
Reader stream)
throws ProcessingException {
DocumentFragment frag = null;
Writer writer;
Reader reader;
boolean removeRoot = true;
try {
// create a writer,
// write the root element, then the input from the
// reader
writer = new StringWriter();
writer.write(XML_ROOT_DEFINITION);
char[] cbuf = new char[16384];
int len;
do {
len = stream.read(cbuf, 0, 16384);
if (len != -1) {
writer.write(cbuf, 0, len);
}
} while (len != -1);
writer.write("</root>");
// now test if xml input start with <?xml
String xml = writer.toString();
String searchString = XML_ROOT_DEFINITION+"<?xml ";
if (xml.startsWith(searchString) == true) {
// now remove the surrounding root element
xml = xml.substring(XML_ROOT_DEFINITION.length(),
xml.length()-7);
removeRoot = false;
}
reader = new StringReader(xml);
InputSource input = new InputSource(reader);
DOMBuilder builder = new DOMBuilder();
builder.startDocument();
builder.startElement("", "cocoon", "cocoon", new
AttributesImpl());
IncludeXMLConsumer filter = new IncludeXMLConsumer(builder,
builder);
parser.parse(input, filter);
builder.endElement("", "cocoon", "cocoon");
builder.endDocument();
// Create Document Fragment, remove <root>
final Document doc = builder.getDocument();
frag = doc.createDocumentFragment();
final Node root = doc.getDocumentElement().getFirstChild();
root.normalize();
if (removeRoot == false) {
root.getParentNode().removeChild(root);
frag.appendChild(root);
} else {
Node child;
while (root.hasChildNodes() == true) {
child = root.getFirstChild();
root.removeChild(child);
frag.appendChild(child);
}
}
} catch (SAXException sax) {
throw new ProcessingException("SAXException: " + sax, sax);
} catch (IOException ioe) {
throw new ProcessingException("IOException: " + ioe, ioe);
}
return frag;
}
/**
* Create a parameter object from xml.
* The xml is flat and consists of elements which all have exactly one
text node:
* <parone>value_one<parone>
* <partwo>value_two<partwo>
* A parameter can occur more than once with different values.
* If <CODE>source</CODE> is not specified a new paramter object is
created
* otherwise the parameters are added to source.
*/
public static SourceParameters createParameters(Node fragment,
SourceParameters source) {
SourceParameters par = (source == null ? new SourceParameters() :
source);
if (fragment != null) {
NodeList childs = fragment.getChildNodes();
if (childs != null) {
Node current;
for(int i = 0; i < childs.getLength(); i++) {
current = childs.item(i);
// only element nodes
if (current.getNodeType() == Node.ELEMENT_NODE) {
current.normalize();
NodeList valueChilds = current.getChildNodes();
String key;
StringBuffer valueBuffer;
String value;
key = current.getNodeName();
valueBuffer = new StringBuffer();
for(int m = 0; m < valueChilds.getLength(); m++) {
current = valueChilds.item(m); // attention:
current is reused here!
if (current.getNodeType() == Node.TEXT_NODE) { //
only text nodes
if (valueBuffer.length() > 0)
valueBuffer.append(' ');
valueBuffer.append(current.getNodeValue());
}
}
value = valueBuffer.toString().trim();
if (key != null && value != null && value.length() >
0) {
par.setParameter(key, value);
}
}
}
}
}
return par;
}
/**
* Create a string from a DOM document fragment.
* Only the top level text nodes are chained together to build the text.
*/
public static String createText(DocumentFragment fragment) {
StringBuffer value = new StringBuffer();
if (fragment != null) {
NodeList childs = fragment.getChildNodes();
if (childs != null) {
Node current;
for(int i = 0; i < childs.getLength(); i++) {
current = childs.item(i);
// only text nodes
if (current.getNodeType() == Node.TEXT_NODE) {
if (value.length() > 0) value.append(' ');
value.append(current.getNodeValue());
}
}
}
}
return value.toString().trim();
}
/**
* Create a new empty DOM document.
*/
public static Document createDocument()
throws ProcessingException {
try {
DocumentBuilderFactory documentFactory =
DocumentBuilderFactory.newInstance();
documentFactory.setNamespaceAware(true);
documentFactory.setValidating(false);
DocumentBuilder docBuilder = documentFactory.newDocumentBuilder();
return docBuilder.newDocument();
} catch (ParserConfigurationException pce) {
throw new ProcessingException("Creating document failed.", pce);
}
}
/**
* Compare all attributes of two elements.
* This method returns true only if both nodes have the same number of
* attributes and the same attributes with equal values.
* Namespace definition nodes are ignored
*/
public static boolean compareAttributes(Element first, Element second) {
NamedNodeMap attr1 = first.getAttributes();
NamedNodeMap attr2 = second.getAttributes();
String value;
if (attr1 == null && attr2 == null) return true;
int attr1Len = (attr1 == null ? 0 : attr1.getLength());
int attr2Len = (attr2 == null ? 0 : attr2.getLength());
if (attr1Len > 0) {
int l = attr1.getLength();
for(int i=0;i<l;i++) {
if (attr1.item(i).getNodeName().startsWith("xmlns:") == true)
attr1Len--;
}
}
if (attr2Len > 0) {
int l = attr2.getLength();
for(int i=0;i<l;i++) {
if (attr2.item(i).getNodeName().startsWith("xmlns:") == true)
attr2Len--;
}
}
if (attr1Len != attr2Len) return false;
int i, l;
int m, l2;
i = 0;
l = attr1.getLength();
l2 = attr2.getLength();
boolean ok = true;
// each attribute of first must be in second with the same value
while (i < l && ok == true) {
value = attr1.item(i).getNodeName();
if (value.startsWith("xmlns:") == false) {
ok = false;
m = 0;
while (m < l2 && ok == false) {
if (attr2.item(m).getNodeName().equals(value) == true) {
// same name, same value?
ok =
attr1.item(i).getNodeValue().equals(attr2.item(m).getNodeValue());
}
m++;
}
}
i++;
}
return ok;
}
/**
* Use an XPath string to select a single node. XPath namespace
* prefixes are resolved from the context node, which may not
* be what you want (see the next method).
*
* @param contextNode The node to start searching from.
* @param str A valid XPath string.
* @return The first node found that matches the XPath, or null.
*
* @throws TransformerException
*/
public static Node getSingleNode(Node contextNode, String str)
throws TransformerException {
String[] pathComponents = XMLUtil.buildPathArray(str);
if (pathComponents == null) {
return XPathAPI.selectSingleNode(contextNode, str);
} else {
return XMLUtil.getFirstNodeFromPath(contextNode, pathComponents,
false);
}
}
/**
* Use an XPath string to select a nodelist.
* XPath namespace prefixes are resolved from the contextNode.
*
* @param contextNode The node to start searching from.
* @param str A valid XPath string.
* @return A NodeIterator, should never be null.
*
* @throws TransformerException
*/
public static NodeList selectNodeList(Node contextNode, String str)
throws TransformerException {
String[] pathComponents = XMLUtil.buildPathArray(str);
if (pathComponents == null) {
return XPathAPI.selectNodeList(contextNode, str);
} else {
return XMLUtil.getNodeListFromPath(contextNode, pathComponents);
}
}
/**
* Build the input for the get...FromPath methods. If the XPath
* expression cannot be handled by the methods, <code>null</code>
* is returned.
*/
public static String[] buildPathArray(String xpath) {
String[] result = null;
if (xpath != null && xpath.charAt(0) != '/') {
// test
int components = 1;
int i, l;
l = xpath.length();
boolean found = false;
i = 0;
while (i < l && found == false) {
switch (xpath.charAt(i)) {
case '[' : found = true; break;
case '(' : found = true; break;
case '*' : found = true; break;
case '@' : found = true; break;
case ':' : found = true; break;
case '/' : components++;
default: i++;
}
}
if (found == false) {
result = new String[components];
if (components == 1) {
result[components-1] = xpath;
} else {
i = 0;
int start = 0;
components = 0;
while (i < l) {
if (xpath.charAt(i) == '/') {
result[components] = xpath.substring(start, i);
start = i+1;
components++;
}
i++;
}
result[components] = xpath.substring(start);
}
}
}
return result;
}
/**
* Use a path to select the first occurence of a node. The namespace
* of a node is ignored!
* @param contextNode The node starting the search.
* @param path The path to search the node. The
* contextNode is searched for a child named path[0],
* this node is searched for a child named path[1]...
* @param create If a child with the corresponding name is not found
* and create is set, this node will be created.
*/
public static Node getFirstNodeFromPath(Node contextNode,
final String[] path,
final boolean create) {
if (contextNode == null || path == null || path.length == 0)
return contextNode;
// first test if the node exists
Node item = XMLUtil.getFirstNodeFromPath(contextNode, path, 0);
if (item == null && create == true) {
int i = 0;
NodeList childs;
boolean found;
int m, l;
while (contextNode != null && i < path.length) {
childs = contextNode.getChildNodes();
found = false;
if (childs != null) {
m = 0;
l = childs.getLength();
while (found == false && m < l) {
item = childs.item(m);
if (item.getNodeType() == Document.ELEMENT_NODE
&& item.getLocalName().equals(path[i]) == true) {
found = true;
contextNode = item;
}
m++;
}
}
if (found == false) {
Element e =
contextNode.getOwnerDocument().createElementNS(null, path[i]);
contextNode.appendChild(e);
contextNode = e;
}
i++;
}
item = contextNode;
}
return item;
}
/**
* Private helper method for getFirstNodeFromPath()
*/
private static Node getFirstNodeFromPath(final Node contextNode,
final String[] path,
final int startIndex) {
int i = 0;
NodeList childs;
boolean found;
int l;
Node item = null;
childs = contextNode.getChildNodes();
found = false;
if (childs != null) {
i = 0;
l = childs.getLength();
while (found == false && i < l) {
item = childs.item(i);
if (item.getNodeType() == Document.ELEMENT_NODE
&& item.getLocalName().equals(path[startIndex]) == true) {
if (startIndex == path.length-1) {
found = true;
} else {
item = XMLUtil.getFirstNodeFromPath(item, path,
startIndex+1);
if (item != null) found = true;
}
}
if (found == false) {
i++;
}
}
if (found == false) {
item = null;
}
}
return item;
}
/**
* Use a path to select all occurences of a node. The namespace
* of a node is ignored!
* @param contextNode The node starting the search.
* @param path The path to search the node. The
* contextNode is searched for a child named path[0],
* this node is searched for a child named path[1]...
*/
public static NodeList getNodeListFromPath(Node contextNode,
String[] path) {
if (contextNode == null) return new NodeListImpl();
if (path == null || path.length == 0) {
return new NodeListImpl(new Node[] {contextNode});
}
NodeListImpl result = new NodeListImpl();
getNodesFromPath(result, contextNode, path, 0);
return result;
}
/**
* Helper method for getNodeListFromPath()
*/
private static void getNodesFromPath(final NodeListImpl result,
final Node contextNode,
final String[] path,
final int startIndex) {
final NodeList childs = contextNode.getChildNodes();
int m, l;
Node item;
if (startIndex == (path.length-1)) {
if (childs != null) {
m = 0;
l = childs.getLength();
while (m < l) {
item = childs.item(m);
if (item.getNodeType() == Document.ELEMENT_NODE
&& item.getLocalName().equals(path[startIndex]) ==
true) {
result.addNode(item);
}
m++;
}
}
} else {
if (childs != null) {
m = 0;
l = childs.getLength();
while (m < l) {
item = childs.item(m);
if (item.getNodeType() == Document.ELEMENT_NODE
&& item.getLocalName().equals(path[startIndex]) ==
true) {
getNodesFromPath(result, item, path, startIndex+1);
}
m++;
}
}
}
}
/**
* Convert umlaute to entities
*/
public static String encode(String value) {
StringBuffer buffer = new StringBuffer(value);
for(int i = 0; i < buffer.length(); i++) {
if (buffer.charAt(i) > 127) {
buffer.replace(i, i+1, "__"+((int)buffer.charAt(i))+";");
}
}
return buffer.toString();
}
/**
* Convert entities to umlaute
*/
public static String decode(String value) {
StringBuffer buffer = new StringBuffer(value);
int pos;
boolean found;
for(int i = 0; i < buffer.length(); i++) {
if (buffer.charAt(i) == '_' &&
buffer.charAt(i+1) == '_') {
pos = i + 2;
found = false;
while (buffer.charAt(pos) >= '0'
&& buffer.charAt(pos) <= '9') {
found = true;
pos++;
}
if (found == true
&& pos > i + 2
&& buffer.charAt(pos) == ';') {
int ent = new Integer(buffer.substring(i+2,
pos)).intValue();
buffer.replace(i, pos+1, ""+ (char)ent);
}
}
}
return buffer.toString();
}
}
----------------------------------------------------------------------
In case of troubles, e-mail: [EMAIL PROTECTED]
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]