Author: woonsan
Date: Mon Jul 6 13:37:17 2009
New Revision: 791479
URL: http://svn.apache.org/viewvc?rev=791479&view=rev
Log:
JS2-1040: Fixing classloader conflicts between portal and portlet contexts.
Also, making dom4j-based element be able to serialize by org.w3c.dom.Element
interface.
Added:
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/dom/
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/dom/DOMAttributeNodeMapImpl.java
(with props)
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/dom/DOMElementImpl.java
(with props)
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/dom/DOMNodeHelperImpl.java
(with props)
Modified:
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/container/impl/PortletResponseContextImpl.java
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/DOMUtils.java
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/java/org/apache/jetspeed/util/TestDOMUtils.java
Modified:
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/container/impl/PortletResponseContextImpl.java
URL:
http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/container/impl/PortletResponseContextImpl.java?rev=791479&r1=791478&r2=791479&view=diff
==============================================================================
---
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/container/impl/PortletResponseContextImpl.java
(original)
+++
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/container/impl/PortletResponseContextImpl.java
Mon Jul 6 13:37:17 2009
@@ -103,7 +103,36 @@
public Element createElement(String tagName) throws DOMException
{
- return DOMUtils.createSerializableElement(tagName);
+ Element element = null;
+
+ // Currently, Jetspeed uses dom4j to create a serializable dom element.
+ // However, dom4j depends on Class.forName() to manage singleton, which
+ // results another org.dom4j.DocumentFactory singleton which comes
from another
+ // classloader such as PA's or common's.
+ // Therefore, we need to switch back to the portal's classloader
during creation.
+
+ ClassLoader paCL = Thread.currentThread().getContextClassLoader();
+ ClassLoader portalCL = JetspeedRequestContext.class.getClassLoader();
+ boolean switchCLs = (paCL != portalCL);
+
+ try
+ {
+ if (switchCLs)
+ {
+ Thread.currentThread().setContextClassLoader(portalCL);
+ }
+
+ element = DOMUtils.createSerializableElement(tagName);
+ }
+ finally
+ {
+ if (switchCLs)
+ {
+ Thread.currentThread().setContextClassLoader(paCL);
+ }
+ }
+
+ return element;
}
public void close()
Modified:
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/DOMUtils.java
URL:
http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/DOMUtils.java?rev=791479&r1=791478&r2=791479&view=diff
==============================================================================
---
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/DOMUtils.java
(original)
+++
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/DOMUtils.java
Mon Jul 6 13:37:17 2009
@@ -19,16 +19,15 @@
import java.io.IOException;
import java.io.StringWriter;
+import org.apache.jetspeed.util.dom.DOMElementImpl;
import org.dom4j.dom.DOMCDATA;
import org.dom4j.dom.DOMComment;
-import org.dom4j.dom.DOMDocument;
import org.dom4j.dom.DOMElement;
import org.dom4j.dom.DOMText;
import org.dom4j.io.HTMLWriter;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
@@ -53,42 +52,7 @@
public static org.w3c.dom.Element createSerializableElement(String tagName)
{
- // Note: Because the DOMElement of dom4j (v1.6.1) is built on DOM
Level2 API,
- // it does not have implementations on setTextContent() and
getTextContent() of
- // org.w3c.dom.Node interface.
- // However, Jetspeed is supporting Java 1.5 from v2.2, we need to
provide this
- // to allow the methods invocations.
- // Also, because dom4j DOMElement does not support getOwnerDocument(),
- // we need to provide the method to allow portlet codes to create
nodes with document.
-
- return new DOMElement(tagName)
- {
- private static final long serialVersionUID = 1L;
-
- private Document document;
-
- @Override
- public Document getOwnerDocument()
- {
- if (document == null)
- {
- document = new DOMDocument(this);
- }
-
- return document;
- }
-
- public void setTextContent(String textContent)
- {
- setText(textContent);
- }
-
- public String getTextContent()
- {
- return getText();
- }
- };
-
+ return new DOMElementImpl(tagName);
}
public static org.w3c.dom.Element
convertToSerializableElement(org.w3c.dom.Element element)
Added:
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/dom/DOMAttributeNodeMapImpl.java
URL:
http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/dom/DOMAttributeNodeMapImpl.java?rev=791479&view=auto
==============================================================================
---
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/dom/DOMAttributeNodeMapImpl.java
(added)
+++
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/dom/DOMAttributeNodeMapImpl.java
Mon Jul 6 13:37:17 2009
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.util.dom;
+
+import org.dom4j.dom.DOMAttributeNodeMap;
+import org.dom4j.dom.DOMElement;
+import org.w3c.dom.Node;
+
+public class DOMAttributeNodeMapImpl extends DOMAttributeNodeMap
+{
+
+ private DOMElement element;
+
+ public DOMAttributeNodeMapImpl(DOMElement element)
+ {
+ super(element);
+
+ this.element = element;
+ }
+
+ public Node item(int index)
+ {
+ return DOMNodeHelperImpl.asDOMAttr(element.attribute(index));
+ }
+
+}
Propchange:
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/dom/DOMAttributeNodeMapImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/dom/DOMAttributeNodeMapImpl.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange:
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/dom/DOMAttributeNodeMapImpl.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added:
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/dom/DOMElementImpl.java
URL:
http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/dom/DOMElementImpl.java?rev=791479&view=auto
==============================================================================
---
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/dom/DOMElementImpl.java
(added)
+++
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/dom/DOMElementImpl.java
Mon Jul 6 13:37:17 2009
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.util.dom;
+
+import org.dom4j.Namespace;
+import org.dom4j.QName;
+import org.dom4j.dom.DOMDocument;
+import org.dom4j.dom.DOMElement;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.NodeList;
+
+/**
+ * Note: Because the DOMElement of dom4j (v1.6.1) is built on DOM Level2 API,
it does not have implementations on setTextContent() and getTextContent() of
+ * org.w3c.dom.Node interface. However, in Java 1.5 environment, we need to
allow the methods invocations. Also, because dom4j DOMElement does not support
+ * getOwnerDocument(), we need to provide the method to create nodes with
document.
+ *
+ * @version $Id$
+ */
+public class DOMElementImpl extends DOMElement
+{
+
+ private static final long serialVersionUID = 1L;
+
+ private Document document;
+
+ public DOMElementImpl(String name)
+ {
+ super(name);
+ }
+
+ public DOMElementImpl(QName qname)
+ {
+ super(qname);
+ }
+
+ public DOMElementImpl(QName qname, int attributeCount)
+ {
+ super(qname, attributeCount);
+ }
+
+ public DOMElementImpl(String name, Namespace namespace)
+ {
+ super(name, namespace);
+ }
+
+ @Override
+ public Document getOwnerDocument()
+ {
+ if (document == null)
+ {
+ document = new DOMDocument(this);
+ }
+
+ return document;
+ }
+
+ public void setTextContent(String textContent)
+ {
+ setText(textContent);
+ }
+
+ public String getTextContent()
+ {
+ return getText();
+ }
+
+ public NamedNodeMap getAttributes()
+ {
+ return new DOMAttributeNodeMapImpl(this);
+ }
+
+ public NodeList getChildNodes()
+ {
+ return DOMNodeHelperImpl.createNodeList(content());
+ }
+
+}
Propchange:
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/dom/DOMElementImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/dom/DOMElementImpl.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange:
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/dom/DOMElementImpl.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added:
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/dom/DOMNodeHelperImpl.java
URL:
http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/dom/DOMNodeHelperImpl.java?rev=791479&view=auto
==============================================================================
---
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/dom/DOMNodeHelperImpl.java
(added)
+++
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/dom/DOMNodeHelperImpl.java
Mon Jul 6 13:37:17 2009
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.util.dom;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.List;
+
+import org.dom4j.Node;
+import org.dom4j.dom.DOMNodeHelper;
+import org.w3c.dom.NodeList;
+
+public class DOMNodeHelperImpl extends DOMNodeHelper
+{
+
+ protected DOMNodeHelperImpl()
+ {
+ super();
+ }
+
+ public static org.w3c.dom.Attr asDOMAttr(final Node attribute)
+ {
+ if (attribute == null)
+ {
+ return null;
+ }
+ else if (attribute instanceof org.w3c.dom.Attr)
+ {
+ return (org.w3c.dom.Attr) attribute;
+ }
+ else
+ {
+ InvocationHandler handler = new InvocationHandler()
+ {
+ public Object invoke(Object proxy, Method method, Object[]
args) throws Throwable
+ {
+ String methodName = method.getName();
+ if ("getName".equals(methodName))
+ {
+ return attribute.getName();
+ }
+ else if ("getValue".equals(methodName))
+ {
+ return attribute.getText();
+ }
+ else
+ {
+ notSupported();
+ }
+ return null;
+ }
+ };
+
+ return (org.w3c.dom.Attr)
Proxy.newProxyInstance(attribute.getClass().getClassLoader(), new Class[] {
org.w3c.dom.Attr.class }, handler);
+ }
+ }
+
+ // Helper methods
+ //
-------------------------------------------------------------------------
+ public static NodeList createNodeList(final List list)
+ {
+ return new NodeList()
+ {
+ public org.w3c.dom.Node item(int index)
+ {
+ if (index >= getLength())
+ {
+ /*
+ * From the NodeList specification: If index is greater
than or equal to the number of nodes in the list, this returns null.
+ */
+ return null;
+ }
+ else
+ {
+ return DOMNodeHelperImpl.asDOMNode((Node) list.get(index));
+ }
+ }
+
+ public int getLength()
+ {
+ return list.size();
+ }
+ };
+ }
+
+ public static org.w3c.dom.Node asDOMNode(final Node node)
+ {
+ if (node == null)
+ {
+ return null;
+ }
+ org.w3c.dom.Node domNode = null;
+ if (node instanceof org.w3c.dom.Node)
+ {
+ domNode = (org.w3c.dom.Node) node;
+ }
+ else
+ {
+ switch (node.getNodeType())
+ {
+ case Node.ELEMENT_NODE:
+ domNode = (org.dom4j.dom.DOMElement) node;
+ break;
+ case Node.TEXT_NODE:
+ case Node.CDATA_SECTION_NODE:
+ case Node.COMMENT_NODE:
+ case Node.ENTITY_REFERENCE_NODE:
+ case Node.PROCESSING_INSTRUCTION_NODE:
+ {
+ InvocationHandler handler = new InvocationHandler()
+ {
+ public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable
+ {
+ String methodName = method.getName();
+ if ("getNodeType".equals(methodName))
+ {
+ return node.getNodeType();
+ }
+ else if ("getNodeValue".equals(methodName) ||
"getData".equals(methodName))
+ {
+ return node.getText();
+ }
+ else if ("getNodeName".equals(methodName))
+ {
+ return node.getName();
+ }
+ else
+ {
+ notSupported();
+ }
+ return null;
+ }
+ };
+ domNode = (org.w3c.dom.Node)
Proxy.newProxyInstance(node.getClass().getClassLoader(), new Class[] {
org.w3c.dom.Node.class }, handler);
+ break;
+ }
+ default:
+ System.out.println("Cannot convert: " + node + " into a
W3C DOM Node");
+ notSupported();
+ break;
+ }
+ }
+
+ return domNode;
+ }
+
+}
Propchange:
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/dom/DOMNodeHelperImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/dom/DOMNodeHelperImpl.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange:
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/dom/DOMNodeHelperImpl.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified:
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/java/org/apache/jetspeed/util/TestDOMUtils.java
URL:
http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/java/org/apache/jetspeed/util/TestDOMUtils.java?rev=791479&r1=791478&r2=791479&view=diff
==============================================================================
---
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/java/org/apache/jetspeed/util/TestDOMUtils.java
(original)
+++
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/java/org/apache/jetspeed/util/TestDOMUtils.java
Mon Jul 6 13:37:17 2009
@@ -16,7 +16,9 @@
*/
package org.apache.jetspeed.util;
+import java.io.IOException;
import java.io.Serializable;
+import java.io.StringWriter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
@@ -141,4 +143,32 @@
assertTrue("the text content is wrong.", stringified.contains("Hello,
World!"));
}
+ public void testDOM4JWriting() throws Exception
+ {
+ org.w3c.dom.Element element =
DOMUtils.createSerializableElement("script");
+ element.setAttribute("id", "my-test-javascript");
+ element.setAttribute("type", "text/javascript");
+ element.setTextContent("alert('<Hello, World!>');");
+
+ String stringified = null;
+ StringWriter writer = new StringWriter(80);
+
+ try
+ {
+ DOMElementWriter domWriter = new DOMElementWriter();
+ domWriter.write(element, writer, 0, " ");
+ }
+ catch (IOException e)
+ {
+ }
+
+ stringified = writer.toString();
+ System.out.println("stringified: " + stringified);
+ assertTrue("element name is different.", stringified.contains("<script
"));
+ assertTrue("id attribute does not exist.",
stringified.contains("id=\"my-test-javascript\""));
+ assertTrue("type attribute does not exist.",
stringified.contains("type=\"text/javascript\""));
+ assertTrue("the text content is wrong.",
stringified.contains("alert("));
+ assertTrue("the text content is wrong.", stringified.contains("Hello,
World!"));
+ }
+
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]