You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jetspeed-dev@portals.apache.org by wo...@apache.org on 2009/04/01 16:10:28 UTC
svn commit: r760898 - in /portals/jetspeed-2/portal/trunk: ./
components/jetspeed-cm/src/test/java/org/apache/jetspeed/cache/
components/jetspeed-portal/
components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/
components/jetspeed-...
Author: woonsan
Date: Wed Apr 1 14:10:20 2009
New Revision: 760898
URL: http://svn.apache.org/viewvc?rev=760898&view=rev
Log:
JS2-949: Adding basic createElement() and addProperty() implementation for head element contribution.
Now, all contributed head elements are stored in portlet content object as serializable elements.
Added:
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/DOMElementWriter.java (with props)
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/DOMUtils.java (with props)
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/java/org/apache/jetspeed/util/
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/java/org/apache/jetspeed/util/TestDOMUtils.java (with props)
Modified:
portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/test/java/org/apache/jetspeed/cache/TestContentCache.java
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/pom.xml
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/PortletContentImpl.java
portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/container/impl/PortletRenderResponseContextImpl.java
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/ (props changed)
portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/aggregator/PortletContent.java
portals/jetspeed-2/portal/trunk/pom.xml
Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/test/java/org/apache/jetspeed/cache/TestContentCache.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/test/java/org/apache/jetspeed/cache/TestContentCache.java?rev=760898&r1=760897&r2=760898&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/test/java/org/apache/jetspeed/cache/TestContentCache.java (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-cm/src/test/java/org/apache/jetspeed/cache/TestContentCache.java Wed Apr 1 14:10:20 2009
@@ -16,8 +16,10 @@
*/
package org.apache.jetspeed.cache;
+import java.io.NotSerializableException;
import java.io.PrintWriter;
import java.security.Principal;
+import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
@@ -30,6 +32,7 @@
import org.apache.jetspeed.cache.impl.EhPortletContentCacheImpl;
import org.apache.jetspeed.cache.impl.JetspeedCacheKeyGenerator;
import org.apache.jetspeed.mockobjects.request.MockRequestContext;
+import org.w3c.dom.Element;
import com.mockrunner.mock.web.MockHttpServletRequest;
import com.mockrunner.mock.web.MockHttpServletResponse;
@@ -388,6 +391,20 @@
// TODO Auto-generated method stub
}
+
+
+ public void addHeadElement(Element element, String keyHint) throws NotSerializableException
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+
+ public Collection<Element> getHeadElements()
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
}
}
Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-portal/pom.xml
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-portal/pom.xml?rev=760898&r1=760897&r2=760898&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-portal/pom.xml (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-portal/pom.xml Wed Apr 1 14:10:20 2009
@@ -134,7 +134,14 @@
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
-
+ <dependency>
+ <groupId>jaxen</groupId>
+ <artifactId>jaxen</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>dom4j</groupId>
+ <artifactId>dom4j</artifactId>
+ </dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/PortletContentImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/PortletContentImpl.java?rev=760898&r1=760897&r2=760898&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/PortletContentImpl.java (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/aggregator/impl/PortletContentImpl.java Wed Apr 1 14:10:20 2009
@@ -17,11 +17,19 @@
package org.apache.jetspeed.aggregator.impl;
import java.io.CharArrayWriter;
+import java.io.NotSerializableException;
import java.io.PrintWriter;
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
import org.apache.jetspeed.aggregator.PortletContent;
import org.apache.jetspeed.aggregator.PortletRenderer;
import org.apache.jetspeed.cache.ContentCacheKey;
+import org.apache.jetspeed.util.DOMUtils;
+import org.w3c.dom.Element;
public class PortletContentImpl implements PortletContent
@@ -34,6 +42,7 @@
private String title;
private String contentType;
private PortletRenderer renderer = null;
+ private Map<String, Element> headElements = null;
PortletContentImpl()
{
@@ -176,4 +185,54 @@
cw.reset();
}
}
+
+ public void addHeadElement(Element element, String keyHint) throws NotSerializableException
+ {
+ if (this.headElements == null)
+ {
+ this.headElements = new HashMap<String, Element>();
+ }
+
+ if (element == null)
+ {
+ if (keyHint != null)
+ {
+ this.headElements.remove(keyHint);
+ }
+
+ return;
+ }
+
+ if (!(element instanceof Serializable))
+ {
+ throw new NotSerializableException("The element is not serializable.");
+ }
+
+ if (keyHint == null)
+ {
+ if (element instanceof org.dom4j.Element)
+ {
+ keyHint = DOMUtils.stringifyElement((org.dom4j.Element) element);
+ }
+ else
+ {
+ keyHint = DOMUtils.stringifyElement(element);
+ }
+ }
+
+ this.headElements.put(keyHint, element);
+ }
+
+ public Collection<Element> getHeadElements()
+ {
+ if (this.headElements != null)
+ {
+ return this.headElements.values();
+ }
+ else
+ {
+ return Collections.emptyList();
+ }
+ }
+
}
\ No newline at end of file
Modified: portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/container/impl/PortletRenderResponseContextImpl.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/container/impl/PortletRenderResponseContextImpl.java?rev=760898&r1=760897&r2=760898&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/container/impl/PortletRenderResponseContextImpl.java (original)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/container/impl/PortletRenderResponseContextImpl.java Wed Apr 1 14:10:20 2009
@@ -18,19 +18,24 @@
package org.apache.jetspeed.container.impl;
import java.io.IOException;
+import java.io.NotSerializableException;
import java.io.OutputStream;
import java.io.PrintWriter;
+import java.io.Serializable;
import java.util.Collection;
+import javax.portlet.MimeResponse;
import javax.portlet.PortletMode;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.jetspeed.aggregator.PortletContent;
+import org.apache.jetspeed.container.PortletWindow;
+import org.apache.jetspeed.util.DOMUtils;
import org.apache.pluto.container.PortletContainer;
import org.apache.pluto.container.PortletRenderResponseContext;
import org.apache.pluto.container.util.PrintWriterServletOutputStream;
-import org.apache.jetspeed.aggregator.PortletContent;
-import org.apache.jetspeed.container.PortletWindow;
+import org.w3c.dom.Element;
/**
* @version $Id$
@@ -124,5 +129,52 @@
{
portletContent.setTitle(title);
}
- }
+ }
+
+ @Override
+ public void addProperty(String key, Element element)
+ {
+ if (MimeResponse.MARKUP_HEAD_ELEMENT.equals(key))
+ {
+ Element headElement = null;
+
+ if (element instanceof Serializable)
+ {
+ headElement = element;
+ }
+ else
+ {
+ headElement = DOMUtils.convertToSerializableElement(element);
+ }
+
+ try
+ {
+ // ID attribute of element is used as keyHint for the head element if available.
+ this.portletContent.addHeadElement(headElement, getIdAttribute(element));
+ }
+ catch (NotSerializableException e)
+ {
+ }
+ }
+ else
+ {
+ super.addProperty(key, element);
+ }
+ }
+
+ private String getIdAttribute(Element element)
+ {
+ String value = null;
+
+ if (element.hasAttribute("ID"))
+ value = element.getAttribute("ID");
+ else if (element.hasAttribute("id"))
+ value = element.getAttribute("id");
+ else if (element.hasAttribute("Id"))
+ value = element.getAttribute("Id");
+ else if (element.hasAttribute("iD"))
+ value = element.getAttribute("iD");
+
+ return value;
+ }
}
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=760898&r1=760897&r2=760898&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 Wed Apr 1 14:10:20 2009
@@ -24,6 +24,7 @@
import org.apache.jetspeed.container.PortletWindow;
import org.apache.jetspeed.container.providers.ResourceURLProviderImpl;
import org.apache.jetspeed.request.JetspeedRequestContext;
+import org.apache.jetspeed.util.DOMUtils;
import org.apache.pluto.container.PortletContainer;
import org.apache.pluto.container.PortletResponseContext;
import org.apache.pluto.container.ResourceURLProvider;
@@ -102,8 +103,7 @@
public Element createElement(String tagName) throws DOMException
{
- // TODO: create DOM element in a more optimized way.
- return null;
+ return DOMUtils.createSerializableElement(tagName);
}
public void close()
Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/
------------------------------------------------------------------------------
--- svn:ignore (original)
+++ svn:ignore Wed Apr 1 14:10:20 2009
@@ -1,2 +1,2 @@
-target
+target
surefire*.properties
Added: portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/DOMElementWriter.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/DOMElementWriter.java?rev=760898&view=auto
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/DOMElementWriter.java (added)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/DOMElementWriter.java Wed Apr 1 14:10:20 2009
@@ -0,0 +1,572 @@
+/*
+ * 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;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import org.w3c.dom.Attr;
+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;
+
+/**
+ * Writes a DOM tree to a given Writer.
+ * warning: this utility currently does not declare XML Namespaces.
+ * <p>Utility class used by {@link org.apache.jetspeed.util.DOMUtils}.</p>
+ */
+public class DOMElementWriter {
+
+ private static final int HEX = 16;
+
+ /** prefix for generated prefixes */
+ private static final String NS = "ns";
+
+ /** xml declaration is on by default */
+ private boolean xmlDeclaration = true;
+
+ /**
+ * XML Namespaces are ignored by default.
+ */
+ private XmlNamespacePolicy namespacePolicy = XmlNamespacePolicy.IGNORE;
+
+ /**
+ * Map (URI to prefix) of known namespaces.
+ */
+ private HashMap nsPrefixMap = new HashMap();
+
+ /**
+ * Number of generated prefix to use next.
+ */
+ private int nextPrefix = 0;
+
+ /**
+ * Map (Element to URI) of namespaces defined on a given element.
+ */
+ private HashMap nsURIByElement = new HashMap();
+
+ /**
+ * Whether namespaces should be ignored for elements and attributes.
+ */
+ public static class XmlNamespacePolicy {
+ private boolean qualifyElements;
+ private boolean qualifyAttributes;
+
+ /**
+ * Ignores namespaces for elements and attributes, the default.
+ */
+ public static final XmlNamespacePolicy IGNORE =
+ new XmlNamespacePolicy(false, false);
+
+ /**
+ * Ignores namespaces for attributes.
+ */
+ public static final XmlNamespacePolicy ONLY_QUALIFY_ELEMENTS =
+ new XmlNamespacePolicy(true, false);
+
+ /**
+ * Qualifies namespaces for elements and attributes.
+ */
+ public static final XmlNamespacePolicy QUALIFY_ALL =
+ new XmlNamespacePolicy(true, true);
+
+ /**
+ * @param qualifyElements whether to qualify elements
+ * @param qualifyAttributes whether to qualify elements
+ */
+ public XmlNamespacePolicy(boolean qualifyElements,
+ boolean qualifyAttributes) {
+ this.qualifyElements = qualifyElements;
+ this.qualifyAttributes = qualifyAttributes;
+ }
+ }
+
+ /**
+ * Create an element writer.
+ * The ?xml? declaration will be included, namespaces ignored.
+ */
+ public DOMElementWriter() {
+ }
+
+ /**
+ * Create an element writer
+ * XML namespaces will be ignored.
+ * @param xmlDeclaration flag to indicate whether the ?xml? declaration
+ * should be included.
+ */
+ public DOMElementWriter(boolean xmlDeclaration) {
+ this(xmlDeclaration, XmlNamespacePolicy.IGNORE);
+ }
+
+ /**
+ * Create an element writer
+ * XML namespaces will be ignored.
+ * @param xmlDeclaration flag to indicate whether the ?xml? declaration
+ * should be included.
+ * @param namespacePolicy the policy to use.
+ */
+ public DOMElementWriter(boolean xmlDeclaration,
+ XmlNamespacePolicy namespacePolicy) {
+ this.xmlDeclaration = xmlDeclaration;
+ this.namespacePolicy = namespacePolicy;
+ }
+
+ private static String lSep = System.getProperty("line.separator");
+
+ // CheckStyle:VisibilityModifier OFF - bc
+ /**
+ * Don't try to be too smart but at least recognize the predefined
+ * entities.
+ */
+ protected String[] knownEntities = {"gt", "amp", "lt", "apos", "quot"};
+ // CheckStyle:VisibilityModifier ON
+
+
+ /**
+ * Writes a DOM tree to a stream in UTF8 encoding. Note that
+ * it prepends the <?xml version='1.0' encoding='UTF-8'?> if
+ * the xmlDeclaration field is true.
+ * The indent number is set to 0 and a 2-space indent.
+ * @param root the root element of the DOM tree.
+ * @param out the outputstream to write to.
+ * @throws IOException if an error happens while writing to the stream.
+ */
+ public void write(Element root, OutputStream out) throws IOException {
+ Writer wri = new OutputStreamWriter(out, "UTF8");
+ writeXMLDeclaration(wri);
+ write(root, wri, 0, " ");
+ wri.flush();
+ }
+
+ /**
+ * Writes the XML declaration if xmlDeclaration is true.
+ * @param wri the writer to write to.
+ * @throws IOException if there is an error.
+ */
+ public void writeXMLDeclaration(Writer wri) throws IOException {
+ if (xmlDeclaration) {
+ wri.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+ }
+ }
+
+ /**
+ * Writes a DOM tree to a stream.
+ *
+ * @param element the Root DOM element of the tree
+ * @param out where to send the output
+ * @param indent number of
+ * @param indentWith string that should be used to indent the
+ * corresponding tag.
+ * @throws IOException if an error happens while writing to the stream.
+ */
+ public void write(Element element, Writer out, int indent,
+ String indentWith)
+ throws IOException {
+
+ // Write child elements and text
+ NodeList children = element.getChildNodes();
+ boolean hasChildren = (children.getLength() > 0);
+ boolean hasChildElements = false;
+ openElement(element, out, indent, indentWith, hasChildren);
+
+ if (hasChildren) {
+ for (int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+
+ switch (child.getNodeType()) {
+
+ case Node.ELEMENT_NODE:
+ hasChildElements = true;
+ if (i == 0) {
+ out.write(lSep);
+ }
+ write((Element) child, out, indent + 1, indentWith);
+ break;
+
+ case Node.TEXT_NODE:
+ out.write(encode(child.getNodeValue()));
+ break;
+
+ case Node.COMMENT_NODE:
+ out.write("<!--");
+ out.write(encode(child.getNodeValue()));
+ out.write("-->");
+ break;
+
+ case Node.CDATA_SECTION_NODE:
+ out.write("<![CDATA[");
+ out.write(encodedata(((Text) child).getData()));
+ out.write("]]>");
+ break;
+
+ case Node.ENTITY_REFERENCE_NODE:
+ out.write('&');
+ out.write(child.getNodeName());
+ out.write(';');
+ break;
+
+ case Node.PROCESSING_INSTRUCTION_NODE:
+ out.write("<?");
+ out.write(child.getNodeName());
+ String data = child.getNodeValue();
+ if (data != null && data.length() > 0) {
+ out.write(' ');
+ out.write(data);
+ }
+ out.write("?>");
+ break;
+ default:
+ // Do nothing
+ }
+ }
+ closeElement(element, out, indent, indentWith, hasChildElements);
+ }
+ }
+
+ /**
+ * Writes the opening tag - including all attributes -
+ * corresponding to a DOM element.
+ *
+ * @param element the DOM element to write
+ * @param out where to send the output
+ * @param indent number of
+ * @param indentWith string that should be used to indent the
+ * corresponding tag.
+ * @throws IOException if an error happens while writing to the stream.
+ */
+ public void openElement(Element element, Writer out, int indent,
+ String indentWith)
+ throws IOException {
+ openElement(element, out, indent, indentWith, true);
+ }
+
+ /**
+ * Writes the opening tag - including all attributes -
+ * corresponding to a DOM element.
+ *
+ * @param element the DOM element to write
+ * @param out where to send the output
+ * @param indent number of
+ * @param indentWith string that should be used to indent the
+ * corresponding tag.
+ * @param hasChildren whether this element has children.
+ * @throws IOException if an error happens while writing to the stream.
+ */
+ public void openElement(Element element, Writer out, int indent,
+ String indentWith, boolean hasChildren)
+ throws IOException {
+ // Write indent characters
+ for (int i = 0; i < indent; i++) {
+ out.write(indentWith);
+ }
+
+ // Write element
+ out.write("<");
+ if (namespacePolicy.qualifyElements) {
+ String uri = getNamespaceURI(element);
+ String prefix = (String) nsPrefixMap.get(uri);
+ if (prefix == null) {
+ if (nsPrefixMap.isEmpty()) {
+ // steal default namespace
+ prefix = "";
+ } else {
+ prefix = NS + (nextPrefix++);
+ }
+ nsPrefixMap.put(uri, prefix);
+ addNSDefinition(element, uri);
+ }
+ if (!"".equals(prefix)) {
+ out.write(prefix);
+ out.write(":");
+ }
+ }
+ out.write(element.getTagName());
+
+ // Write attributes
+ NamedNodeMap attrs = element.getAttributes();
+ for (int i = 0; i < attrs.getLength(); i++) {
+ Attr attr = (Attr) attrs.item(i);
+ out.write(" ");
+ if (namespacePolicy.qualifyAttributes) {
+ String uri = getNamespaceURI(attr);
+ String prefix = (String) nsPrefixMap.get(uri);
+ if (prefix == null) {
+ prefix = NS + (nextPrefix++);
+ nsPrefixMap.put(uri, prefix);
+ addNSDefinition(element, uri);
+ }
+ out.write(prefix);
+ out.write(":");
+ }
+ out.write(attr.getName());
+ out.write("=\"");
+ out.write(encode(attr.getValue()));
+ out.write("\"");
+ }
+
+ // write namespace declarations
+ ArrayList al = (ArrayList) nsURIByElement.get(element);
+ if (al != null) {
+ Iterator iter = al.iterator();
+ while (iter.hasNext()) {
+ String uri = (String) iter.next();
+ String prefix = (String) nsPrefixMap.get(uri);
+ out.write(" xmlns");
+ if (!"".equals(prefix)) {
+ out.write(":");
+ out.write(prefix);
+ }
+ out.write("=\"");
+ out.write(uri);
+ out.write("\"");
+ }
+ }
+
+ if (hasChildren) {
+ out.write(">");
+ } else {
+ removeNSDefinitions(element);
+ out.write(" />");
+ out.write(lSep);
+ out.flush();
+ }
+ }
+
+ /**
+ * Writes a DOM tree to a stream.
+ *
+ * @param element the Root DOM element of the tree
+ * @param out where to send the output
+ * @param indent number of
+ * @param indentWith string that should be used to indent the
+ * corresponding tag.
+ * @param hasChildren if true indent.
+ * @throws IOException if an error happens while writing to the stream.
+ */
+ public void closeElement(Element element, Writer out, int indent,
+ String indentWith, boolean hasChildren)
+ throws IOException {
+ // If we had child elements, we need to indent before we close
+ // the element, otherwise we're on the same line and don't need
+ // to indent
+ if (hasChildren) {
+ for (int i = 0; i < indent; i++) {
+ out.write(indentWith);
+ }
+ }
+
+ // Write element close
+ out.write("</");
+ if (namespacePolicy.qualifyElements) {
+ String uri = getNamespaceURI(element);
+ String prefix = (String) nsPrefixMap.get(uri);
+ if (prefix != null && !"".equals(prefix)) {
+ out.write(prefix);
+ out.write(":");
+ }
+ removeNSDefinitions(element);
+ }
+ out.write(element.getTagName());
+ out.write(">");
+ out.write(lSep);
+ out.flush();
+ }
+
+ /**
+ * Escape <, > & ', " as their entities and
+ * drop characters that are illegal in XML documents.
+ * @param value the string to encode.
+ * @return the encoded string.
+ */
+ public String encode(String value) {
+ StringBuffer sb = new StringBuffer();
+ int len = value.length();
+ for (int i = 0; i < len; i++) {
+ char c = value.charAt(i);
+ switch (c) {
+ case '<':
+ sb.append("<");
+ break;
+ case '>':
+ sb.append(">");
+ break;
+ case '\'':
+ sb.append("'");
+ break;
+ case '\"':
+ sb.append(""");
+ break;
+ case '&':
+ int nextSemi = value.indexOf(";", i);
+ if (nextSemi < 0
+ || !isReference(value.substring(i, nextSemi + 1))) {
+ sb.append("&");
+ } else {
+ sb.append('&');
+ }
+ break;
+ default:
+ if (isLegalCharacter(c)) {
+ sb.append(c);
+ }
+ break;
+ }
+ }
+ return sb.substring(0);
+ }
+
+ /**
+ * Drop characters that are illegal in XML documents.
+ *
+ * <p>Also ensure that we are not including an <code>]]></code>
+ * marker by replacing that sequence with
+ * <code>&#x5d;&#x5d;&gt;</code>.</p>
+ *
+ * <p>See XML 1.0 2.2 <a
+ * href="http://www.w3.org/TR/1998/REC-xml-19980210#charsets">
+ * http://www.w3.org/TR/1998/REC-xml-19980210#charsets</a> and
+ * 2.7 <a
+ * href="http://www.w3.org/TR/1998/REC-xml-19980210#sec-cdata-sect">http://www.w3.org/TR/1998/REC-xml-19980210#sec-cdata-sect</a>.</p>
+ * @param value the value to be encoded.
+ * @return the encoded value.
+
+ */
+ public String encodedata(final String value) {
+ StringBuffer sb = new StringBuffer();
+ int len = value.length();
+ for (int i = 0; i < len; ++i) {
+ char c = value.charAt(i);
+ if (isLegalCharacter(c)) {
+ sb.append(c);
+ }
+ }
+
+ String result = sb.substring(0);
+ int cdEnd = result.indexOf("]]>");
+ while (cdEnd != -1) {
+ sb.setLength(cdEnd);
+ // CheckStyle:MagicNumber OFF
+ sb.append("]]>")
+ .append(result.substring(cdEnd + 3));
+ // CheckStyle:MagicNumber ON
+ result = sb.substring(0);
+ cdEnd = result.indexOf("]]>");
+ }
+
+ return result;
+ }
+
+ /**
+ * Is the given argument a character or entity reference?
+ * @param ent the value to be checked.
+ * @return true if it is an entity.
+ */
+ public boolean isReference(String ent) {
+ if (!(ent.charAt(0) == '&') || !ent.endsWith(";")) {
+ return false;
+ }
+
+ if (ent.charAt(1) == '#') {
+ if (ent.charAt(2) == 'x') {
+ try {
+ // CheckStyle:MagicNumber OFF
+ Integer.parseInt(ent.substring(3, ent.length() - 1), HEX);
+ // CheckStyle:MagicNumber ON
+ return true;
+ } catch (NumberFormatException nfe) {
+ return false;
+ }
+ } else {
+ try {
+ Integer.parseInt(ent.substring(2, ent.length() - 1));
+ return true;
+ } catch (NumberFormatException nfe) {
+ return false;
+ }
+ }
+ }
+
+ String name = ent.substring(1, ent.length() - 1);
+ for (int i = 0; i < knownEntities.length; i++) {
+ if (name.equals(knownEntities[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Is the given character allowed inside an XML document?
+ *
+ * <p>See XML 1.0 2.2 <a
+ * href="http://www.w3.org/TR/1998/REC-xml-19980210#charsets">
+ * http://www.w3.org/TR/1998/REC-xml-19980210#charsets</a>.</p>
+ * @param c the character to test.
+ * @return true if the character is allowed.
+ */
+ public boolean isLegalCharacter(char c) {
+ // CheckStyle:MagicNumber OFF
+ if (c == 0x9 || c == 0xA || c == 0xD) {
+ return true;
+ } else if (c < 0x20) {
+ return false;
+ } else if (c <= 0xD7FF) {
+ return true;
+ } else if (c < 0xE000) {
+ return false;
+ } else if (c <= 0xFFFD) {
+ return true;
+ }
+ // CheckStyle:MagicNumber ON
+ return false;
+ }
+
+ private void removeNSDefinitions(Element element) {
+ ArrayList al = (ArrayList) nsURIByElement.get(element);
+ if (al != null) {
+ Iterator iter = al.iterator();
+ while (iter.hasNext()) {
+ nsPrefixMap.remove(iter.next());
+ }
+ nsURIByElement.remove(element);
+ }
+ }
+
+ private void addNSDefinition(Element element, String uri) {
+ ArrayList al = (ArrayList) nsURIByElement.get(element);
+ if (al == null) {
+ al = new ArrayList();
+ nsURIByElement.put(element, al);
+ }
+ al.add(uri);
+ }
+
+ private static String getNamespaceURI(Node n) {
+ String uri = n.getNamespaceURI();
+ if (uri == null) {
+ // FIXME: Is "No Namespace is Empty Namespace" really OK?
+ uri = "";
+ }
+ return uri;
+ }
+}
Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/DOMElementWriter.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/DOMElementWriter.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/DOMElementWriter.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: 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=760898&view=auto
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/DOMUtils.java (added)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/DOMUtils.java Wed Apr 1 14:10:20 2009
@@ -0,0 +1,174 @@
+/*
+ * 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;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+import org.dom4j.dom.DOMCDATA;
+import org.dom4j.dom.DOMComment;
+import org.dom4j.dom.DOMElement;
+import org.dom4j.dom.DOMText;
+import org.dom4j.io.OutputFormat;
+import org.dom4j.io.XMLWriter;
+import org.w3c.dom.Attr;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class DOMUtils
+{
+
+ public static final int DEFAULT_ELEMENT_STRINGIFYING_BUFFER_SIZE = 80;
+ public static final int DEFAULT_INDENT = 0;
+ public static final String DEFAULT_INDENT_WITH = "\t";
+
+ private DOMUtils()
+ {
+ }
+
+ public static org.w3c.dom.Element createSerializableElement(String tagName)
+ {
+ return new DOMElement(tagName)
+ {
+ private static final long serialVersionUID = 1L;
+
+ public void setTextContent(String textContent)
+ {
+ setText(textContent);
+ }
+
+ public String getTextContent()
+ {
+ return getText();
+ }
+ };
+ }
+
+ public static org.w3c.dom.Element convertToSerializableElement(org.w3c.dom.Element element)
+ {
+ return (org.w3c.dom.Element) convertElement(element);
+ }
+
+ public static org.dom4j.Element convertElement(org.w3c.dom.Element element)
+ {
+ DOMElement domElement = (DOMElement) createSerializableElement(element.getNodeName());
+
+ NamedNodeMap attrs = element.getAttributes();
+
+ for (int i = 0; i < attrs.getLength(); i++)
+ {
+ Attr attr = (Attr) attrs.item(i);
+ domElement.setAttribute(attr.getName(), attr.getValue());
+ }
+
+ NodeList children = element.getChildNodes();
+ boolean hasChildren = (children.getLength() > 0);
+
+ if (hasChildren)
+ {
+ for (int i = 0; i < children.getLength(); i++)
+ {
+ Node child = children.item(i);
+
+ switch (child.getNodeType())
+ {
+ case Node.ELEMENT_NODE:
+ domElement.add(convertElement((org.w3c.dom.Element) child));
+ break;
+ case Node.TEXT_NODE:
+ domElement.add(new DOMText(child.getNodeValue()));
+ break;
+ case Node.COMMENT_NODE:
+ domElement.add(new DOMComment(child.getNodeValue()));
+ break;
+ case Node.CDATA_SECTION_NODE:
+ domElement.add(new DOMCDATA(child.getNodeValue()));
+ break;
+ default:
+ // Do not support entity reference node and processing instruction node.
+ }
+ }
+ }
+
+ return domElement;
+ }
+
+ public static String stringifyElement(org.w3c.dom.Element element)
+ {
+ return stringifyElement(element, DEFAULT_ELEMENT_STRINGIFYING_BUFFER_SIZE, DEFAULT_INDENT, DEFAULT_INDENT_WITH);
+ }
+
+ public static String stringifyElement(org.w3c.dom.Element element, int initialBufferSize, int indent, String indentWith)
+ {
+ String stringified = null;
+ StringWriter writer = new StringWriter(initialBufferSize);
+
+ try
+ {
+ DOMElementWriter domWriter = new DOMElementWriter();
+ domWriter.write(element, writer, indent, indentWith);
+ }
+ catch (IOException e)
+ {
+ }
+
+ stringified = writer.toString();
+ return stringified;
+ }
+
+ public static String stringifyElement(org.dom4j.Element element)
+ {
+ return stringifyElement(element, DEFAULT_ELEMENT_STRINGIFYING_BUFFER_SIZE, DEFAULT_INDENT_WITH);
+ }
+
+ public static String stringifyElement(org.dom4j.Element element, int initialBufferSize, String indentWith)
+ {
+ OutputFormat outputFormat = new OutputFormat();
+ outputFormat.setIndent(indentWith);
+ return stringifyElement(element, initialBufferSize, outputFormat);
+ }
+
+ public static String stringifyElement(org.dom4j.Element element, int initialBufferSize, OutputFormat outputFormat)
+ {
+ String stringified = null;
+ StringWriter writer = new StringWriter(initialBufferSize);
+ XMLWriter xmlWriter = null;
+
+ try
+ {
+ xmlWriter = new XMLWriter(writer, outputFormat);
+ xmlWriter.write(element);
+ xmlWriter.flush();
+ xmlWriter.close();
+ }
+ catch (IOException e)
+ {
+ }
+ finally
+ {
+ if (xmlWriter != null)
+ {
+ try { xmlWriter.close(); } catch (IOException ce) { }
+ }
+ }
+
+ stringified = writer.toString();
+ return stringified;
+ }
+
+}
Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/DOMUtils.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/DOMUtils.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/main/java/org/apache/jetspeed/util/DOMUtils.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: 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=760898&view=auto
==============================================================================
--- portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/java/org/apache/jetspeed/util/TestDOMUtils.java (added)
+++ portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/java/org/apache/jetspeed/util/TestDOMUtils.java Wed Apr 1 14:10:20 2009
@@ -0,0 +1,115 @@
+/*
+ * 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;
+
+import java.io.Serializable;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import junit.framework.TestCase;
+
+import org.apache.commons.lang.SerializationUtils;
+import org.w3c.dom.CDATASection;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+public class TestDOMUtils extends TestCase
+{
+
+ public void testW3CDOMElement() throws Exception
+ {
+ DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
+ DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
+ Document doc = docBuilder.newDocument();
+ Element element = doc.createElement("script");
+ element.setAttribute("id", "my-test-javascript");
+ element.setAttribute("type", "text/javascript");
+ element.setTextContent("alert('<Hello, World!>');");
+ Element child = doc.createElement("source");
+ child.setAttribute("id", "my-test-javascript-source");
+ child.setTextContent("source is available.");
+ element.appendChild(child);
+
+ String stringified = DOMUtils.stringifyElement(element);
+ 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!"));
+ assertTrue("the child element is wrong.", stringified.contains("<source id=\"my-test-javascript-source\">source is available.</source>"));
+
+ Element converted = (Element) DOMUtils.convertElement(element);
+ assertTrue("converted element is not serializable!", converted instanceof Serializable);
+ assertEquals("converted element name is wrong.", element.getNodeName(), converted.getNodeName());
+
+ Element deserialized = (Element) SerializationUtils.clone((Serializable) converted);
+ assertEquals("deserialized element name is wrong.", converted.getNodeName(), deserialized.getNodeName());
+ stringified = DOMUtils.stringifyElement((org.dom4j.Element) deserialized);
+ System.out.println("deserialized element's stringified: " + stringified);
+ assertTrue("deserialized 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!"));
+ assertTrue("the child element is wrong.", stringified.contains("<source id=\"my-test-javascript-source\">source is available.</source>"));
+
+ stringified = DOMUtils.stringifyElement((org.dom4j.Element) converted);
+ System.out.println("converted element's stringified: " + stringified);
+ assertTrue("converted 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!"));
+ assertTrue("the child element is wrong.", stringified.contains("<source id=\"my-test-javascript-source\">source is available.</source>"));
+
+ element = doc.createElement("script");
+ element.setAttribute("id", "my-test-javascript");
+ element.setAttribute("type", "text/javascript");
+ CDATASection cdataSection = doc.createCDATASection("alert('<Hello, World!>');");
+ element.appendChild(cdataSection);
+ child = doc.createElement("source");
+ child.setAttribute("id", "my-test-javascript-source");
+ child.setTextContent("source is available.");
+ element.appendChild(child);
+
+ stringified = DOMUtils.stringifyElement(element);
+ System.out.println("stringified: " + stringified);
+ assertTrue("the text content is wrong.", stringified.contains("<![CDATA[alert("));
+ assertTrue("the text content is wrong.", stringified.contains("Hello, World!"));
+ assertTrue("the child element is wrong.", stringified.contains("<source id=\"my-test-javascript-source\">source is available.</source>"));
+ }
+
+ public void testDOM4JElement() 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 = DOMUtils.stringifyElement((org.dom4j.Element) element);
+
+ 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!"));
+ }
+
+}
Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/java/org/apache/jetspeed/util/TestDOMUtils.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/java/org/apache/jetspeed/util/TestDOMUtils.java
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: portals/jetspeed-2/portal/trunk/components/jetspeed-portal/src/test/java/org/apache/jetspeed/util/TestDOMUtils.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/aggregator/PortletContent.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/aggregator/PortletContent.java?rev=760898&r1=760897&r2=760898&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/aggregator/PortletContent.java (original)
+++ portals/jetspeed-2/portal/trunk/jetspeed-api/src/main/java/org/apache/jetspeed/aggregator/PortletContent.java Wed Apr 1 14:10:20 2009
@@ -16,9 +16,12 @@
*/
package org.apache.jetspeed.aggregator;
+import java.io.NotSerializableException;
import java.io.PrintWriter;
+import java.util.Collection;
import org.apache.jetspeed.cache.ContentCacheKey;
+import org.w3c.dom.Element;
/**
* <p>
@@ -68,6 +71,12 @@
* @return
*/
int getExpiration();
+
+ /**
+ * Sets the expiration setting for this content.
+ *
+ * @param expiration
+ */
void setExpiration(int expiration);
/**
@@ -90,10 +99,47 @@
*/
void setTitle(String title);
+ /**
+ * Gets the content type of this portlet content.
+ *
+ * @return
+ */
String getContentType();
+
+ /**
+ * Sets the content type of this portlet content.
+ *
+ * @param contentType
+ */
void setContentType(String contentType);
+
+ /**
+ * Adds an header element to be contributed to the page.
+ * If keyHint argument is provided and if a header element
+ * with the provided key hint already exists, then
+ * the element will be overwritten to the item.
+ * If the element is null and keyHint is not null,
+ * the element with the keyHint is removed from the response.
+ * If the element is not null and keyHint is null,
+ * then the keyHint will be automatically generated by the element content.
+ * Meanwhile, the element should implement java.io.Serializable.
+ * Otherwise it will throw a java.io.NotSerializableException.
+ *
+ * @param element
+ * @param keyHint
+ * @throws NotSerializableException
+ */
+ void addHeadElement(Element element, String keyHint) throws NotSerializableException;
+
+ /**
+ * Retrieves header element list to be contributed to the page.
+ *
+ * @return List with head element items
+ */
+ Collection<Element> getHeadElements();
void reset();
+
void resetBuffer();
/**
Modified: portals/jetspeed-2/portal/trunk/pom.xml
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/portal/trunk/pom.xml?rev=760898&r1=760897&r2=760898&view=diff
==============================================================================
--- portals/jetspeed-2/portal/trunk/pom.xml (original)
+++ portals/jetspeed-2/portal/trunk/pom.xml Wed Apr 1 14:10:20 2009
@@ -811,14 +811,13 @@
<version>${ehcache.version}</version>
</dependency>
- <!-- defining dom4j (which is included by commons-configuration) just to be able to exclude
+ <!-- defining dom4j just to be able to exclude
isorelax, msv and relaxngDatatype
-->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
- <optional>true</optional>
- <version>[1.4,)</version>
+ <version>1.6.1</version>
<exclusions>
<exclusion>
<groupId>isorelax</groupId>
---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org