You are viewing a plain text version of this content. The canonical link for it is here.
Posted to svn@forrest.apache.org by th...@apache.org on 2008/10/02 14:28:53 UTC

svn commit: r701104 - in /forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/impl/helper: NSAllocator.java XSLContractHelper.java

Author: thorsten
Date: Thu Oct  2 05:28:52 2008
New Revision: 701104

URL: http://svn.apache.org/viewvc?rev=701104&view=rev
Log:
FOR-1118
The problem had been that the structurer processing worked differently in cocoon and junit.

This was caused by the cocoon serializer. It seems to be a feature that it only declares once the xmlns. Preferable in the root element.

Due to this fact the namespace declaration for e.g. the forrest prefix never had been written to the return source from the processTemplate method. Provoking the code to fail when started in cocoon.

I overcame this problem by adding a custom implementation (NSAllocator) for the XMLEventAllocator interface. It is not optimal since it will always add the xmlns declaration to the element if a prefix is used.

The better way would have been to write all namespaces from the NamespaceContext to the first start element. However this is not possible since the interface does not return an iterator of all registered namespaces without an input parameter. There should be a Iterator getNamespaces(), but there is not. :(

Added:
    forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/impl/helper/NSAllocator.java   (with props)
Modified:
    forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/impl/helper/XSLContractHelper.java

Added: forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/impl/helper/NSAllocator.java
URL: http://svn.apache.org/viewvc/forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/impl/helper/NSAllocator.java?rev=701104&view=auto
==============================================================================
--- forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/impl/helper/NSAllocator.java (added)
+++ forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/impl/helper/NSAllocator.java Thu Oct  2 05:28:52 2008
@@ -0,0 +1,123 @@
+/*
+ * 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.forrest.dispatcher.impl.helper;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.Namespace;
+import javax.xml.stream.events.XMLEvent;
+import javax.xml.stream.util.XMLEventAllocator;
+import javax.xml.stream.util.XMLEventConsumer;
+
+import com.ctc.wstx.evt.DefaultEventAllocator;
+
+/**
+ * This allocator will add always the xmlns declaration for the prefix used in
+ * the start element. Be aware that even if a parent element already declared the
+ * same namespace we will declare it again and again. Meaning the allocator is
+ * not aware of heredity of namespaces.
+ * 
+ * @version 1.0
+ */
+public class NSAllocator extends DefaultEventAllocator implements
+    XMLEventAllocator {
+
+  private XMLEventFactory eventFactory;
+
+  protected NSAllocator(boolean accurateLocation) {
+    super(accurateLocation);
+    eventFactory = XMLEventFactory.newInstance();
+  }
+
+  /*
+   * @seecom.ctc.wstx.evt.DefaultEventAllocator#allocate(javax.xml.stream.
+   * XMLStreamReader, javax.xml.stream.util.XMLEventConsumer)
+   */
+  @SuppressWarnings("unchecked")
+  public void allocate(XMLStreamReader reader, XMLEventConsumer consumer)
+      throws XMLStreamException {
+    XMLEvent event = allocate(reader);
+    if (event != null) {
+      if (event.isStartElement()) {
+        QName name = event.asStartElement().getName();
+        Iterator attributes = allocateAttributes(reader);
+        Iterator namespaces = allocateNamespaces(name, reader);
+        XMLEvent startElement = eventFactory.createStartElement(name,
+            attributes, namespaces);
+        consumer.add(startElement);
+      } else {
+        if (event.isEndDocument()) {
+        }
+        consumer.add(event);
+      }
+    }
+  }
+
+  /**
+   * Here we calculate the namespaces. If we do not find a declaration for a
+   * prefixed node we will see if it is in the NameSpaceContext and create it.
+   * 
+   * @param name qname of the node that we are working with
+   * @param reader the underlying stream reader.
+   * @return iterator of the calculated namespaces. 
+   */
+  private Iterator<Namespace> allocateNamespaces(QName name,
+      XMLStreamReader reader) {
+    ArrayList<Namespace> namespaces = new ArrayList<Namespace>();
+    Set<String> set = new HashSet<String>();
+    Namespace namespace;
+    for (int i = 0, n = reader.getNamespaceCount(); i < n; ++i) {
+      String prefix = reader.getNamespacePrefix(i);
+      String uri = reader.getNamespaceURI(i);
+      namespace = eventFactory.createNamespace(prefix, uri);
+      namespaces.add(namespace);
+      set.add(prefix);
+    }
+    String prefix = name.getPrefix();
+    if (null != prefix && !prefix.equals("") && !set.contains(prefix)) {
+      NamespaceContext context = reader.getNamespaceContext();
+      String uri = context.getNamespaceURI(prefix);
+      namespace = eventFactory.createNamespace(prefix, uri);
+      namespaces.add(namespace);
+    }
+    return namespaces.iterator();
+  }
+
+  /**
+   * Handy method to create an attribute iterator of the current event.
+   * @param reader the underlying XMLStreamReader.
+   * @return an attribute iterator.
+   */
+  private Iterator<Attribute> allocateAttributes(XMLStreamReader reader) {
+    ArrayList<Attribute> attributes = new ArrayList<Attribute>();
+    for (int i = 0, n = reader.getAttributeCount(); i < n; ++i) {
+      attributes.add(eventFactory.createAttribute(reader.getAttributeName(i),
+          reader.getAttributeValue(i)));
+    }
+    return attributes.iterator();
+  }
+
+}

Propchange: forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/impl/helper/NSAllocator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/impl/helper/XSLContractHelper.java
URL: http://svn.apache.org/viewvc/forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/impl/helper/XSLContractHelper.java?rev=701104&r1=701103&r2=701104&view=diff
==============================================================================
--- forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/impl/helper/XSLContractHelper.java (original)
+++ forrest/branches/dispatcher_rewrite/plugins/org.apache.forrest.plugin.internal.dispatcher/src/java/org/apache/forrest/dispatcher/impl/helper/XSLContractHelper.java Thu Oct  2 05:28:52 2008
@@ -173,7 +173,9 @@
       throws XMLStreamException {
     ByteArrayOutputStream out = new ByteArrayOutputStream();
     XMLEventWriter writer = getWriter(out);
-    XMLEventAllocator allocator = getEventAllocator();
+    // Making sure we always have all ns 
+    // A wee bit brute force but it works
+    XMLEventAllocator allocator = new NSAllocator(true);
     String role = "";
     for (int i = 0; i < reader.getAttributeCount(); i++) {
       // Get attribute name