|
svn commit: r791479 - in /portals/jetspeed-2/portal/trunk/components/jetspe: msg#00011jetspeed-dev-portals.apache.org
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: jetspeed-dev-unsubscribe@xxxxxxxxxxxxxxxxxx For additional commands, e-mail: jetspeed-dev-help@xxxxxxxxxxxxxxxxxx
|
|
||||||||||||||||||||||||||
| News | Mail Home | sitemap | FAQ | advertise |