You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@abdera.apache.org by jm...@apache.org on 2006/10/30 17:26:20 UTC

svn commit: r469180 - in /incubator/abdera/java/trunk: core/src/main/java/org/apache/abdera/factory/ core/src/main/java/org/apache/abdera/model/ examples/src/main/java/org/apache/abdera/examples/extension/ examples/src/main/resources/META-INF/ examples...

Author: jmsnell
Date: Mon Oct 30 08:26:18 2006
New Revision: 469180

URL: http://svn.apache.org/viewvc?view=rev&rev=469180
Log:
Revised Extension model that allows extensions to be developed based on a wrapper/delegation model that
is decoupled from the underlying parsing infrastructure.

 * Add ElementWrapper and ExtensibleElementWrapper to the model APIs
 * Modify ExtensionFactory to return an ElementWrapper for a given Element
 * Modify FOMBuilder and FOMFactory to use the new ExtensionFactoryMap
 * Modify the Feed Thread and OpenSearch extensions to use the new model
 * Add a new extension sample

Added:
    incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/factory/ExtensionFactoryMap.java
    incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/model/ElementWrapper.java
    incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/model/ExtensibleElementWrapper.java
    incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/extension/
    incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/extension/Bar.java
    incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/extension/Example.java
    incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/extension/Foo.java
    incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/extension/FooExtensionFactory.java
    incubator/abdera/java/trunk/examples/src/main/resources/META-INF/
    incubator/abdera/java/trunk/examples/src/main/resources/META-INF/services/
    incubator/abdera/java/trunk/examples/src/main/resources/META-INF/services/org.apache.abdera.factory.ExtensionFactory
    incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/opensearch/IntegerElement.java
    incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/thread/InReplyToImpl.java
    incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/thread/TotalImpl.java
    incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMElementIteratorWrapper.java
Removed:
    incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/opensearch/ItemsPerPage.java
    incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/opensearch/OpenSearchV11Helper.java
    incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/opensearch/StartIndex.java
    incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/opensearch/TotalResults.java
    incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/opensearch/impl/FOMItemsPerPage.java
    incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/opensearch/impl/FOMStartIndex.java
    incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/opensearch/impl/FOMTotalResults.java
    incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/thread/impl/FOMInReplyTo.java
    incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/thread/impl/FOMTotal.java
    incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/FOMExtensionFactory.java
Modified:
    incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/factory/ExtensionFactory.java
    incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/factory/Factory.java
    incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/opensearch/OpenSearchConstants.java
    incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/opensearch/OpenSearchExtensionFactory.java
    incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/opensearch/Query.java
    incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/thread/ThreadExtensionFactory.java
    incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/thread/ThreadHelper.java
    incubator/abdera/java/trunk/extensions/src/test/java/org/apache/abdera/test/ext/opensearch/OpenSearchTest.java
    incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/FOMDocument.java
    incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/FOMElement.java
    incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/FOMExtensibleElement.java
    incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/FOMFactory.java
    incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMExtensionIterator.java
    incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMList.java

Modified: incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/factory/ExtensionFactory.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/factory/ExtensionFactory.java?view=diff&rev=469180&r1=469179&r2=469180
==============================================================================
--- incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/factory/ExtensionFactory.java (original)
+++ incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/factory/ExtensionFactory.java Mon Oct 30 08:26:18 2006
@@ -17,13 +17,10 @@
 */
 package org.apache.abdera.factory;
 
-import javax.xml.namespace.QName;
+import java.util.List;
 
-import org.apache.abdera.model.Base;
 import org.apache.abdera.model.Element;
 
-import java.util.List;
-
 /**
  * <p>
  *   Extension Factories are used to provide a means of dynamically resolving
@@ -46,12 +43,6 @@
  *   the class names of each ExtensionFactory you wish to register.
  * </p>
  * 
- * <p>
- *   Note that at this time, ExtensionFactories are specific to the parser 
- *   implementation used.  That is, if you're using the default StAX-based 
- *   FOMParser and FOMFactory implementation, your ExtensionFactories will 
- *   need to also implement FOMExtensionFactory.
- * </p>
  */
 public interface ExtensionFactory {
 
@@ -61,22 +52,15 @@
   boolean handlesNamespace(String namespace);
 
   /**
-   * Returns the Namespace URIs handled by this Extension Factory.
+   * Returns the Namespace URIs handled by this Extension Factory
    *
    * @return A List of Namespace URIs Supported by this Extension
    */
   List<String> getNamespaces();
 
   /**
-   * Called by the Factory implementaton to create an instance of the 
-   * extension element.  If parent is not null, the new element will 
-   * be automatically added as a child of the parent.
-   * 
-   * @param qname the QName of the extension element
-   * @param parent the Parent of the extension element
-   * @param factory the Factory
-   * @return ExtensionElement The created ExtensionElement
+   * Retrieve an ElementWrapper for the specified Element or return
+   * the parameter itself if a wrapper could not be retrieved
    */
-  <T extends Element>T newExtensionElement(QName qname, Base parent, Factory factory);
-
+  <T extends  Element>T getElementWrapper(Element internal);
 }

Added: incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/factory/ExtensionFactoryMap.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/factory/ExtensionFactoryMap.java?view=auto&rev=469180
==============================================================================
--- incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/factory/ExtensionFactoryMap.java (added)
+++ incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/factory/ExtensionFactoryMap.java Mon Oct 30 08:26:18 2006
@@ -0,0 +1,87 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  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.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.factory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import javax.xml.namespace.QName;
+
+import org.apache.abdera.model.Base;
+import org.apache.abdera.model.Element;
+
+public class ExtensionFactoryMap 
+  implements ExtensionFactory {
+
+  private final List<ExtensionFactory> factories;
+  private final Map<Element,Element> wrappers;
+  
+  public ExtensionFactoryMap(List<ExtensionFactory> factories) {
+    this.factories = factories;
+    this.wrappers = new WeakHashMap<Element,Element>();
+  }
+
+  @SuppressWarnings("unchecked")
+  public <T extends Element> T getElementWrapper(Element internal) {
+    if (internal == null) return null;
+    T t = (T)wrappers.get(internal);
+    if (t == null) {
+      for (ExtensionFactory factory : factories) {
+        t = factory.getElementWrapper(internal);
+        if (t != internal) {
+          wrappers.put(internal, t);
+          return t;
+        }
+      }
+      t = (T) internal;
+    }
+    return t;
+  }
+  
+  public void setElementWrapper(Element internal, Element wrapper) {
+    wrappers.put(internal, wrapper);
+  }
+
+  public List<String> getNamespaces() {
+    List<String> ns = new ArrayList<String>();
+    for (ExtensionFactory factory : factories) {
+      ns.addAll(factory.getNamespaces());
+    }
+    return ns;
+  }
+
+  public boolean handlesNamespace(String namespace) {
+    for (ExtensionFactory factory : factories) {
+      if (factory.handlesNamespace(namespace)) return true;
+    }
+    return false;
+  }
+
+  public <T extends Element> T newExtensionElement(
+    QName qname, 
+    Base parent, 
+    Factory factory) {
+      return null;
+  }
+
+  public List<ExtensionFactory> getFactories() {
+    return factories;
+  }
+}

Modified: incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/factory/Factory.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/factory/Factory.java?view=diff&rev=469180&r1=469179&r2=469180
==============================================================================
--- incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/factory/Factory.java (original)
+++ incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/factory/Factory.java Mon Oct 30 08:26:18 2006
@@ -608,13 +608,6 @@
   Div newDiv(Base parent);
 
   /**
-   * Registers an extension implementation class for this Factory instance only
-   * @param qname The XML QName of the extension element to register
-   * @param impl The implementation class for the extension element
-   */
-  <T extends Base>void registerExtension(QName qname, Class impl);
-  
-  /**
    * Registers an extension factory for this Factory instance only
    * @param extensionFactory An ExtensionFactory instance 
    */
@@ -641,4 +634,9 @@
    * Generate a new random UUID URI 
    */
   String newUuidUri();
+  
+  /**
+   * Set an element wrapper
+   */
+  void setElementWrapper(Element element, Element wrapper);
 }

Added: incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/model/ElementWrapper.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/model/ElementWrapper.java?view=auto&rev=469180
==============================================================================
--- incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/model/ElementWrapper.java (added)
+++ incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/model/ElementWrapper.java Mon Oct 30 08:26:18 2006
@@ -0,0 +1,204 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  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.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.model;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.util.List;
+import java.util.Locale;
+
+import javax.xml.namespace.QName;
+
+import org.apache.abdera.factory.Factory;
+import org.apache.abdera.util.iri.IRI;
+import org.apache.abdera.util.iri.IRISyntaxException;
+
+public abstract class ElementWrapper 
+  implements Element {
+
+  private Element internal;
+  
+  protected ElementWrapper(
+    Element internal) {
+      this.internal = internal;
+  }
+  
+  protected ElementWrapper(Factory factory, QName qname) {
+    Element el = factory.newElement(qname);
+    internal = (el instanceof ElementWrapper) ?
+      ((ElementWrapper)el).getInternal() : el;
+    factory.setElementWrapper(internal, this);
+  }
+
+  public void addComment(
+    String value) {
+      internal.addComment(value);
+  }
+
+  public Object clone() {
+    try {
+      ElementWrapper wrapper = (ElementWrapper) super.clone();
+      wrapper.internal = (Element) internal.clone();
+      return wrapper;
+    } catch (CloneNotSupportedException e) {
+      // won't happen
+      return null;
+    }
+  }
+
+  public void declareNS(String uri, String prefix) {
+    internal.declareNS(uri, prefix);
+  }
+
+  public void discard() {
+    internal.discard();
+  }
+
+  public List<QName> getAttributes() {
+    return internal.getAttributes();
+  }
+
+  public String getAttributeValue(QName qname) {
+    return internal.getAttributeValue(qname);
+  }
+
+  public String getAttributeValue(String name) {
+    return internal.getAttributeValue(name);
+  }
+
+  public IRI getBaseUri() throws IRISyntaxException {
+    return internal.getBaseUri();
+  }
+
+  public <T extends Element> Document<T> getDocument() {
+    return internal.getDocument();
+  }
+
+  public List<QName> getExtensionAttributes() {
+    return internal.getExtensionAttributes();
+  }
+
+  public Factory getFactory() {
+    return internal.getFactory();
+  }
+
+  public <T extends Element> T getFirstChild() {
+    return internal.getFirstChild();
+  }
+
+  public <T extends Element> T getFirstChild(QName qname) {
+    return internal.getFirstChild(qname);
+  }
+
+  public String getLanguage() {
+    return internal.getLanguage();
+  }
+
+  public Locale getLocale() {
+    return internal.getLocale();
+  }
+
+  public <T extends Element> T getNextSibling() {
+    return internal.getNextSibling();
+  }
+
+  public <T extends Element> T getNextSibling(QName qname) {
+    return internal.getNextSibling(qname);
+  }
+
+  public <T extends Base> T getParentElement() {
+    return internal.getParentElement();
+  }
+
+  public <T extends Element> T getPreviousSibling() {
+    return internal.getPreviousSibling();
+  }
+
+  public <T extends Element> T getPreviousSibling(QName qname) {
+    return internal.getPreviousSibling(qname);
+  }
+
+  public QName getQName() {
+    return internal.getQName();
+  }
+
+  public IRI getResolvedBaseUri() throws IRISyntaxException {
+    return internal.getResolvedBaseUri();
+  }
+
+  public String getText() {
+    return internal.getText();
+  }
+
+  public void removeAttribute(QName qname) {
+    internal.removeAttribute(qname);
+  }
+
+  public void setAttributeValue(QName qname, String value) {
+    internal.setAttributeValue(qname, value);
+  }
+
+  public void setAttributeValue(String name, String value) {
+    internal.setAttributeValue(name, value);
+  }
+
+  public void setBaseUri(IRI base) {
+    internal.setBaseUri(base);
+  }
+
+  public void setBaseUri(String base) throws IRISyntaxException {
+    internal.setBaseUri(base);
+  }
+
+  public void setLanguage(String language) {
+    internal.setLanguage(language);
+  }
+
+  public void setParentElement(Element parent) {
+    internal.setParentElement(parent);
+  }
+
+  public void setText(String text) {
+    internal.setText(text);
+  }
+
+  public void writeTo(OutputStream out) throws IOException {
+    internal.writeTo(out);
+  }
+
+  public void writeTo(Writer writer) throws IOException {
+    internal.writeTo(writer);
+  }
+  
+  public boolean equals(Object other) {
+    return internal.equals(other);
+  }
+  
+  public String toString() {
+    return internal.toString();
+  }
+  
+  public int hashCode() {
+    return internal.hashCode();
+  }
+
+  public Element getInternal() {
+    return internal;
+  }
+}

Added: incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/model/ExtensibleElementWrapper.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/model/ExtensibleElementWrapper.java?view=auto&rev=469180
==============================================================================
--- incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/model/ExtensibleElementWrapper.java (added)
+++ incubator/abdera/java/trunk/core/src/main/java/org/apache/abdera/model/ExtensibleElementWrapper.java Mon Oct 30 08:26:18 2006
@@ -0,0 +1,90 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  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.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.model;
+
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import org.apache.abdera.factory.Factory;
+
+public class ExtensibleElementWrapper 
+  extends ElementWrapper 
+  implements ExtensibleElement {
+
+  protected ExtensibleElementWrapper(Element internal) {
+    super(internal);
+  }
+  
+  public ExtensibleElementWrapper(Factory factory, QName qname) {
+    super(factory, qname);
+  }
+
+  private ExtensibleElement getExtInternal() {
+    return (ExtensibleElement) getInternal();
+  }
+  
+  public void addExtension(Element extension) {
+    getExtInternal().addExtension(extension);
+  }
+
+  public <T extends Element> T addExtension(QName qname) {
+    return getExtInternal().addExtension(qname);
+  }
+
+  public <T extends Element> T addExtension(String namespace, String localPart, String prefix) {
+    return getExtInternal().addExtension(namespace, localPart, prefix);
+  }
+
+  public Element addSimpleExtension(QName qname, String value) {
+    return getExtInternal().addSimpleExtension(qname, value);
+  }
+
+  public Element addSimpleExtension(String namespace, String localPart, String prefix, String value) {
+    return getExtInternal().addSimpleExtension(namespace, localPart, prefix, value);
+  }
+
+  public <T extends Element> T getExtension(QName qname) {
+    return getExtInternal().getExtension(qname);
+  }
+
+  public <T extends Element> T getExtension(Class<T> _class) {
+    return getExtInternal().getExtension(_class);
+  }
+
+  public List<Element> getExtensions() {
+    return getExtInternal().getExtensions();
+  }
+
+  public List<Element> getExtensions(String uri) {
+    return getExtInternal().getExtensions(uri);
+  }
+
+  public <T extends Element> List<T> getExtensions(QName qname) {
+    return getExtInternal().getExtensions(qname);
+  }
+
+  public String getSimpleExtension(QName qname) {
+    return getExtInternal().getSimpleExtension(qname);
+  }
+
+  public String getSimpleExtension(String namespace, String localPart, String prefix) {
+    return getExtInternal().getSimpleExtension(namespace, localPart, prefix);
+  }
+  
+}

Added: incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/extension/Bar.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/extension/Bar.java?view=auto&rev=469180
==============================================================================
--- incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/extension/Bar.java (added)
+++ incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/extension/Bar.java Mon Oct 30 08:26:18 2006
@@ -0,0 +1,44 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  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.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.examples.extension;
+
+import javax.xml.namespace.QName;
+
+import org.apache.abdera.factory.Factory;
+import org.apache.abdera.model.Element;
+import org.apache.abdera.model.ExtensibleElementWrapper;
+
+public class Bar 
+  extends ExtensibleElementWrapper {
+
+  public Bar(Element internal) {
+    super(internal);
+  }
+
+  public Bar(Factory factory, QName qname) {
+    super(factory, qname);
+  }
+
+  public void setFoo(Foo foo) {
+    addExtension(foo);
+  }
+  
+  public Foo getFoo() {
+    return getExtension(FooExtensionFactory.FOO);
+  }
+}

Added: incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/extension/Example.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/extension/Example.java?view=auto&rev=469180
==============================================================================
--- incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/extension/Example.java (added)
+++ incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/extension/Example.java Mon Oct 30 08:26:18 2006
@@ -0,0 +1,42 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  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.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.examples.extension;
+
+import org.apache.abdera.Abdera;
+import org.apache.abdera.model.Entry;
+
+public class Example {
+
+  public static void main(String[] args) throws Exception {
+    
+    Abdera abdera = new Abdera();
+    
+    Entry entry = abdera.getFactory().newEntry();
+    
+    Foo foo = entry.addExtension(FooExtensionFactory.FOO);
+    foo.setFoo("foo");
+    
+    Bar bar = entry.addExtension(FooExtensionFactory.BAR);
+    bar.setFoo((Foo) foo.clone());
+    bar.getFoo().setFoo("bar");
+    
+    System.out.println(entry);
+    
+  }
+  
+}

Added: incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/extension/Foo.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/extension/Foo.java?view=auto&rev=469180
==============================================================================
--- incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/extension/Foo.java (added)
+++ incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/extension/Foo.java Mon Oct 30 08:26:18 2006
@@ -0,0 +1,45 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  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.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.examples.extension;
+
+import javax.xml.namespace.QName;
+
+import org.apache.abdera.factory.Factory;
+import org.apache.abdera.model.Element;
+import org.apache.abdera.model.ElementWrapper;
+
+public class Foo 
+  extends ElementWrapper {
+
+  public Foo(Element internal) {
+    super(internal);
+  }
+
+  public Foo(Factory factory, QName qname) {
+    super(factory, qname);
+  }
+
+  public String getFoo() {
+    return getText();
+  }
+  
+  public void setFoo(String foo) {
+    setText(foo);
+  }
+  
+}

Added: incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/extension/FooExtensionFactory.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/extension/FooExtensionFactory.java?view=auto&rev=469180
==============================================================================
--- incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/extension/FooExtensionFactory.java (added)
+++ incubator/abdera/java/trunk/examples/src/main/java/org/apache/abdera/examples/extension/FooExtensionFactory.java Mon Oct 30 08:26:18 2006
@@ -0,0 +1,50 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  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.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.examples.extension;
+
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import org.apache.abdera.factory.ExtensionFactory;
+import org.apache.abdera.model.Element;
+
+public class FooExtensionFactory 
+  implements ExtensionFactory {
+
+  public static final String NS = "tag:example.org,2006:foo";
+  public static final QName FOO = new QName(NS, "foo", "f");
+  public static final QName BAR = new QName(NS, "bar", "f");
+  
+  @SuppressWarnings("unchecked")
+  public <T extends Element> T getElementWrapper(Element internal) {
+    QName qname = internal.getQName();
+    if (FOO.equals(qname)) return (T)new Foo(internal);
+    else if (BAR.equals(qname)) return (T)new Bar(internal);
+    else return (T)internal;
+  }
+
+  public List<String> getNamespaces() {
+    return java.util.Arrays.asList(new String[] {NS});
+  }
+
+  public boolean handlesNamespace(String namespace) {
+    return NS.equals(namespace);
+  }
+
+}

Added: incubator/abdera/java/trunk/examples/src/main/resources/META-INF/services/org.apache.abdera.factory.ExtensionFactory
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/examples/src/main/resources/META-INF/services/org.apache.abdera.factory.ExtensionFactory?view=auto&rev=469180
==============================================================================
--- incubator/abdera/java/trunk/examples/src/main/resources/META-INF/services/org.apache.abdera.factory.ExtensionFactory (added)
+++ incubator/abdera/java/trunk/examples/src/main/resources/META-INF/services/org.apache.abdera.factory.ExtensionFactory Mon Oct 30 08:26:18 2006
@@ -0,0 +1 @@
+org.apache.abdera.examples.extension.FooExtensionFactory
\ No newline at end of file

Added: incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/opensearch/IntegerElement.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/opensearch/IntegerElement.java?view=auto&rev=469180
==============================================================================
--- incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/opensearch/IntegerElement.java (added)
+++ incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/opensearch/IntegerElement.java Mon Oct 30 08:26:18 2006
@@ -0,0 +1,46 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  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.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.ext.opensearch;
+
+import javax.xml.namespace.QName;
+
+import org.apache.abdera.factory.Factory;
+import org.apache.abdera.model.Element;
+import org.apache.abdera.model.ElementWrapper;
+
+public class IntegerElement 
+  extends ElementWrapper {
+
+  public IntegerElement(Element internal) {
+    super(internal);
+  }
+
+  public IntegerElement(Factory factory, QName qname) {
+    super(factory, qname);
+  }
+
+  public int getValue() {
+    String val = getText();
+    return (val != null) ? Integer.parseInt(val) : -1;
+  }
+  
+  public void setValue(int value) {
+    setText(String.valueOf(value));
+  }
+  
+}

Modified: incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/opensearch/OpenSearchConstants.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/opensearch/OpenSearchConstants.java?view=diff&rev=469180&r1=469179&r2=469180
==============================================================================
--- incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/opensearch/OpenSearchConstants.java (original)
+++ incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/opensearch/OpenSearchConstants.java Mon Oct 30 08:26:18 2006
@@ -22,13 +22,24 @@
 public final class OpenSearchConstants {
   private OpenSearchConstants() {}
 
-  public static final String OPENSEARCH_NS = "http://a9.com/-/spec/opensearchrss/1.0/";
+  public static final String OPENSEARCH_V10_NS = "http://a9.com/-/spec/opensearchrss/1.0/";
+  public static final String OPENSEARCH_NS = "http://a9.com/-/spec/opensearchrss/1.1/";
 
   public static final String TOTAL_RESULTS_LN  = "totalResults";
   public static final String ITEMS_PER_PAGE_LN = "itemsPerPage";
   public static final String START_INDEX_LN    = "startIndex";
+  public static final String QUERY_LN          = "Query";
+
+  public static final String OS_PREFIX = "os";
+  
+  public static final QName TOTAL_RESULTS_V10  = new QName(OPENSEARCH_V10_NS, TOTAL_RESULTS_LN);
+  public static final QName ITEMS_PER_PAGE_V10 = new QName(OPENSEARCH_V10_NS, ITEMS_PER_PAGE_LN);
+  public static final QName START_INDEX_V10    = new QName(OPENSEARCH_V10_NS, START_INDEX_LN);
+  public static final QName QUERY_V10          = new QName(OPENSEARCH_V10_NS, QUERY_LN, OS_PREFIX);
+  
+  public static final QName TOTAL_RESULTS  = new QName(OPENSEARCH_NS, TOTAL_RESULTS_LN, OS_PREFIX);
+  public static final QName ITEMS_PER_PAGE = new QName(OPENSEARCH_NS, ITEMS_PER_PAGE_LN, OS_PREFIX);
+  public static final QName START_INDEX    = new QName(OPENSEARCH_NS, START_INDEX_LN, OS_PREFIX);
+  public static final QName QUERY          = new QName(OPENSEARCH_NS, QUERY_LN, OS_PREFIX);
 
-  public static final QName TOTAL_RESULTS  = new QName(OPENSEARCH_NS, TOTAL_RESULTS_LN);
-  public static final QName ITEMS_PER_PAGE = new QName(OPENSEARCH_NS, ITEMS_PER_PAGE_LN);
-  public static final QName START_INDEX    = new QName(OPENSEARCH_NS, START_INDEX_LN);
 }

Modified: incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/opensearch/OpenSearchExtensionFactory.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/opensearch/OpenSearchExtensionFactory.java?view=diff&rev=469180&r1=469179&r2=469180
==============================================================================
--- incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/opensearch/OpenSearchExtensionFactory.java (original)
+++ incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/opensearch/OpenSearchExtensionFactory.java Mon Oct 30 08:26:18 2006
@@ -17,67 +17,44 @@
 */
 package org.apache.abdera.ext.opensearch;
 
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
 import org.apache.abdera.factory.ExtensionFactory;
-import org.apache.abdera.factory.Factory;
-import org.apache.abdera.parser.stax.FOMExtensionFactory;
 import org.apache.abdera.model.Element;
-import org.apache.abdera.model.Base;
-import org.apache.abdera.ext.opensearch.impl.FOMTotalResults;
-import org.apache.abdera.ext.opensearch.impl.FOMItemsPerPage;
-import org.apache.abdera.ext.opensearch.impl.FOMStartIndex;
-
-import org.apache.axiom.om.OMContainer;
-import org.apache.axiom.om.OMFactory;
-import org.apache.axiom.om.OMXMLParserWrapper;
 
-import javax.xml.namespace.QName;
-import java.util.List;
-import java.util.ArrayList;
+public class OpenSearchExtensionFactory 
+  implements ExtensionFactory {
 
-public class OpenSearchExtensionFactory implements ExtensionFactory, FOMExtensionFactory {
-  public boolean handlesNamespace(String ns)
-  {
-    return OpenSearchConstants.OPENSEARCH_NS.equals(ns);
+  @SuppressWarnings("unchecked")
+  public <T extends Element> T getElementWrapper(Element internal) {
+    QName qname = internal.getQName();
+    if (qname.equals(OpenSearchConstants.QUERY) ||
+        qname.equals(OpenSearchConstants.QUERY_V10)) {
+      return (T)new Query(internal);
+    } else if (qname.equals(OpenSearchConstants.ITEMS_PER_PAGE) ||
+               qname.equals(OpenSearchConstants.START_INDEX) ||
+               qname.equals(OpenSearchConstants.TOTAL_RESULTS) ||
+               qname.equals(OpenSearchConstants.ITEMS_PER_PAGE_V10) ||
+               qname.equals(OpenSearchConstants.START_INDEX_V10) ||
+               qname.equals(OpenSearchConstants.TOTAL_RESULTS_V10)) {
+      return (T)new IntegerElement(internal);
+    } else {
+      return (T)internal;
+    }
   }
 
-  public List<String> getNamespaces()
-  {
-    List<String> lst = new ArrayList<String>();
-    lst.add(OpenSearchConstants.OPENSEARCH_NS);
-    return lst;
+  public List<String> getNamespaces() {
+    return java.util.Arrays.asList(
+      new String[] {
+        OpenSearchConstants.OPENSEARCH_NS, 
+        OpenSearchConstants.OPENSEARCH_V10_NS});
   }
 
-  @SuppressWarnings("unchecked")
-  public <T extends Element> T newExtensionElement(QName qname,
-                                                   Base base,
-                                                   Factory factory)
-  {
-    return (T) newExtensionElement(qname, base, factory, null);
+  public boolean handlesNamespace(String namespace) {
+    return OpenSearchConstants.OPENSEARCH_NS.equals(namespace) ||
+           OpenSearchConstants.OPENSEARCH_V10_NS.equals(namespace);
   }
 
-  @SuppressWarnings("unchecked")
-  public <T extends Element> T newExtensionElement(QName qname,
-                                                   Base base,
-                                                   Factory factory,
-                                                   OMXMLParserWrapper parserWrapper)
-  {
-    OMContainer cbase = (OMContainer) base;
-    OMFactory cfactory = (OMFactory) factory;
-    if (OpenSearchConstants.TOTAL_RESULTS.equals(qname)) {
-      return (parserWrapper != null) ?
-        (T) new FOMTotalResults(qname, cbase, cfactory, parserWrapper) :
-        (T) new FOMTotalResults(qname, cbase, cfactory);
-    }
-    else if (OpenSearchConstants.ITEMS_PER_PAGE.equals(qname)) {
-      return (parserWrapper != null) ?
-        (T) new FOMItemsPerPage(qname, cbase, cfactory, parserWrapper) :
-        (T) new FOMItemsPerPage(qname, cbase, cfactory);
-    }
-    else if (OpenSearchConstants.START_INDEX.equals(qname)) {
-      return (parserWrapper != null) ?
-        (T) new FOMStartIndex(qname, cbase, cfactory, parserWrapper) :
-        (T) new FOMStartIndex(qname, cbase, cfactory);
-    }
-    return null;
-  }
 }

Modified: incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/opensearch/Query.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/opensearch/Query.java?view=diff&rev=469180&r1=469179&r2=469180
==============================================================================
--- incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/opensearch/Query.java (original)
+++ incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/opensearch/Query.java Mon Oct 30 08:26:18 2006
@@ -20,10 +20,13 @@
 import javax.xml.namespace.QName;
 
 import org.apache.abdera.Abdera;
+import org.apache.abdera.factory.Factory;
 import org.apache.abdera.model.Element;
+import org.apache.abdera.model.ElementWrapper;
 import org.apache.abdera.model.ExtensibleElement;
 
-public class Query {
+public class Query 
+  extends ElementWrapper {
 
   public enum Role {
     CORRECTION,
@@ -34,31 +37,27 @@
     SUPERSET;
   }
   
-  private final Element internal;
-  
   public Query(Element internal) {
-    this.internal = internal;
+    super(internal);
   }
   
-  public Query(Abdera abdera) {
-    internal = abdera.getFactory().newElement(OpenSearchV11Helper.QUERY);
-  }
-  
-  public Query(ExtensibleElement parent) {
-    parent.declareNS(OpenSearchV11Helper.OPENSEARCH_NS, OpenSearchV11Helper.OS_PREFIX);
-    internal = parent.addExtension(OpenSearchV11Helper.QUERY);
+  public Query(Factory factory) {
+    super(factory, OpenSearchConstants.QUERY);
   }
   
-  public void setParent(ExtensibleElement parent) {
-    parent.addExtension(internal);
+  public Query(Abdera abdera) {
+    this(abdera.getFactory());
   }
   
-  public void discard() {
-    internal.discard();
+  public Query(ExtensibleElement parent) {
+    this(parent.getFactory());
+    parent.declareNS(
+      OpenSearchConstants.OPENSEARCH_NS, 
+      OpenSearchConstants.OS_PREFIX);
   }
   
   public Role getRole() {
-    String role = internal.getAttributeValue("role");
+    String role = getInternal().getAttributeValue("role");
     if (role == null) return null;
     try {
       return Role.valueOf(role.toUpperCase());
@@ -69,154 +68,129 @@
   
   public void setRole(Role role) {
     if (role != null) {
-      internal.setAttributeValue("role", role.name().toLowerCase());
+      getInternal().setAttributeValue("role", role.name().toLowerCase());
     } else {
-      internal.removeAttribute(new QName("role"));
+      getInternal().removeAttribute(new QName("role"));
     }
   }
   
   public String getTitle() {
-    return internal.getAttributeValue("title");
+    return getInternal().getAttributeValue("title");
   }
   
   public void setTitle(String title) {
     if (title != null) {
       if (title.length() > 256) throw new IllegalArgumentException("Title too long (max 256 characters)");
-      internal.setAttributeValue("title", title);
+      getInternal().setAttributeValue("title", title);
     } else {
-      internal.removeAttribute(new QName("title"));
+      getInternal().removeAttribute(new QName("title"));
     }
   }
 
   public int getTotalResults() {
-    String val = internal.getAttributeValue("totalResults");
+    String val = getInternal().getAttributeValue("totalResults");
     return (val != null) ? Integer.parseInt(val) : -1;
   }
   
   public void setTotalResults(int totalResults) {
     if (totalResults > -1) {
-      internal.setAttributeValue("totalResults", String.valueOf(totalResults));
+      getInternal().setAttributeValue("totalResults", String.valueOf(totalResults));
     } else {
-      internal.removeAttribute(new QName("totalResults"));
+      getInternal().removeAttribute(new QName("totalResults"));
     }
   }
   
   public String getSearchTerms() {
-    return internal.getAttributeValue("searchTerms");
+    return getInternal().getAttributeValue("searchTerms");
   }
   
   public void setSearchTerms(String terms) {
     if (terms != null) {
-      internal.setAttributeValue("searchTerms", terms);
+      getInternal().setAttributeValue("searchTerms", terms);
     } else {
-      internal.removeAttribute(new QName("searchTerms"));
+      getInternal().removeAttribute(new QName("searchTerms"));
     }
   }
   
   public int getCount() {
-    String val = internal.getAttributeValue("count");
+    String val = getInternal().getAttributeValue("count");
     return (val != null) ? Integer.parseInt(val) : -1;
   }
   
   public void setCount(int count) {
     if (count > -1) {
-      internal.setAttributeValue("count", String.valueOf(count));
+      getInternal().setAttributeValue("count", String.valueOf(count));
     } else {
-      internal.removeAttribute(new QName("count"));
+      getInternal().removeAttribute(new QName("count"));
     }
   }
   
   public int getStartIndex() {
-    String val = internal.getAttributeValue("startIndex");
+    String val = getInternal().getAttributeValue("startIndex");
     return (val != null) ? Integer.parseInt(val) : -1;
   }
   
   public void setStartIndex(int startIndex) {
     if (startIndex > -1) {
-      internal.setAttributeValue("startIndex", String.valueOf(startIndex));
+      getInternal().setAttributeValue("startIndex", String.valueOf(startIndex));
     } else {
-      internal.removeAttribute(new QName("startIndex"));
+      getInternal().removeAttribute(new QName("startIndex"));
     }
   }
   
   public int getStartPage() {
-    String val = internal.getAttributeValue("startPage");
+    String val = getInternal().getAttributeValue("startPage");
     return (val != null) ? Integer.parseInt(val) : -1;
   }
   
   public void setStartPage(int startPage) {
     if (startPage > -1) {
-      internal.setAttributeValue("startPage", String.valueOf(startPage));
+      getInternal().setAttributeValue("startPage", String.valueOf(startPage));
     } else {
-      internal.removeAttribute(new QName("startPage"));
+      getInternal().removeAttribute(new QName("startPage"));
     }
   }
   
   public String getLanguage() {
-    return internal.getAttributeValue("language");
+    return getInternal().getAttributeValue("language");
   }
   
   public void setLanguage(String language) {
     if (language != null) {
-      internal.setAttributeValue("language", language);
+      getInternal().setAttributeValue("language", language);
     } else {
-      internal.removeAttribute(new QName("language"));
+      getInternal().removeAttribute(new QName("language"));
     }
   }
   
   public String getInputEncoding() {
-    return internal.getAttributeValue("inputEncoding");
+    return getInternal().getAttributeValue("inputEncoding");
   }
   
   public void setInputEncoding(String encoding) {
     if (encoding != null) {
-      internal.setAttributeValue("inputEncoding", encoding);
+      getInternal().setAttributeValue("inputEncoding", encoding);
     } else {
-      internal.removeAttribute(new QName("inputEncoding"));
+      getInternal().removeAttribute(new QName("inputEncoding"));
     }
   }
 
   public String getOutputEncoding() {
-    return internal.getAttributeValue("outputEncoding");
+    return getInternal().getAttributeValue("outputEncoding");
   }
   
   public void setOutputEncoding(String encoding) {
     if (encoding != null) {
-      internal.setAttributeValue("outputEncoding", encoding);
+      getInternal().setAttributeValue("outputEncoding", encoding);
     } else {
-      internal.removeAttribute(new QName("outputEncoding"));
+      getInternal().removeAttribute(new QName("outputEncoding"));
     }
   }
   
-  public String getAttribute(QName qname) {
-    return internal.getAttributeValue(qname);
-  }
-  
-  public void setAttribute(QName qname, String value) {
-    if (value != null) {
-      internal.setAttributeValue(qname, value);
-    } else {
-      internal.removeAttribute(qname);
-    }
-  }
-  
-  @Override
-  public String toString() {
-    return internal.toString();
-  }
-  
-  @Override
-  public boolean equals(Object other) {
-    if (!(other instanceof Query)) return false;
-    Query query = (Query) other;
-    return (internal.equals(query.internal));
-  }
-  
-  @Override
   public int hashCode() {
     final int PRIME = 31;
     int result = super.hashCode();
-    result = PRIME * result + ((internal == null) ? 0 : internal.hashCode());
+    result = PRIME * result + ((getInternal() == null) ? 0 : getInternal().hashCode());
     return result;
   }
 

Added: incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/thread/InReplyToImpl.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/thread/InReplyToImpl.java?view=auto&rev=469180
==============================================================================
--- incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/thread/InReplyToImpl.java (added)
+++ incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/thread/InReplyToImpl.java Mon Oct 30 08:26:18 2006
@@ -0,0 +1,105 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  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.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.ext.thread;
+
+import javax.activation.MimeType;
+import javax.activation.MimeTypeParseException;
+
+import org.apache.abdera.factory.Factory;
+import org.apache.abdera.model.Element;
+import org.apache.abdera.model.ElementWrapper;
+import org.apache.abdera.util.iri.IRI;
+import org.apache.abdera.util.iri.IRISyntaxException;
+
+public class InReplyToImpl 
+  extends ElementWrapper 
+  implements InReplyTo {
+
+  public InReplyToImpl(Element internal) {
+    super(internal);
+  }
+
+  public InReplyToImpl(Factory factory) {
+    super(factory, ThreadConstants.IN_REPLY_TO);
+  }
+
+  public IRI getHref() throws IRISyntaxException {
+    String href = getAttributeValue("href");
+    return (href != null) ? new IRI(href) : null;
+  }
+
+  public MimeType getMimeType() throws MimeTypeParseException {
+    String type = getAttributeValue("type");
+    return (type != null) ? new MimeType(type) : null;
+  }
+
+  public IRI getRef() throws IRISyntaxException {
+    String ref = getAttributeValue("ref");
+    return (ref != null) ? new IRI(ref) : null;
+  }
+
+  public IRI getResolvedHref() throws IRISyntaxException {
+    IRI href = getHref();
+    IRI base = getBaseUri();
+    return (base == null) ? href : (href != null) ? base.resolve(href) : null; 
+  }
+
+  public IRI getResolvedSource() throws IRISyntaxException {
+    IRI href = getSource();
+    IRI base = getBaseUri();
+    return (base == null) ? href : (href != null) ? base.resolve(href) : null;
+  }
+
+  public IRI getSource() throws IRISyntaxException {
+    String source = getAttributeValue("source");
+    return (source != null) ? new IRI(source) : null;
+  }
+
+  public void setHref(IRI ref) {
+    setAttributeValue("href", ref.toString());
+  }
+
+  public void setHref(String ref) throws IRISyntaxException {
+    setAttributeValue("href", ref);
+  }
+
+  public void setMimeType(MimeType mimeType) {
+    setAttributeValue("type", mimeType.toString());
+  }
+
+  public void setMimeType(String mimeType) throws MimeTypeParseException {
+    setAttributeValue("type", mimeType);
+  }
+
+  public void setRef(IRI ref) {
+    setAttributeValue("ref", ref.toString());
+  }
+
+  public void setRef(String ref) throws IRISyntaxException {
+    setAttributeValue("ref", ref);
+  }
+
+  public void setSource(IRI source) {
+    setAttributeValue("source", source.toString());
+  }
+
+  public void setSource(String source) throws IRISyntaxException {
+    setAttributeValue("source", source);
+  }
+
+}

Modified: incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/thread/ThreadExtensionFactory.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/thread/ThreadExtensionFactory.java?view=diff&rev=469180&r1=469179&r2=469180
==============================================================================
--- incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/thread/ThreadExtensionFactory.java (original)
+++ incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/thread/ThreadExtensionFactory.java Mon Oct 30 08:26:18 2006
@@ -17,24 +17,16 @@
 */
 package org.apache.abdera.ext.thread;
 
-import javax.xml.namespace.QName;
-import java.util.List;
 import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.namespace.QName;
 
-import org.apache.abdera.ext.thread.impl.FOMInReplyTo;
-import org.apache.abdera.ext.thread.impl.FOMTotal;
 import org.apache.abdera.factory.ExtensionFactory;
-import org.apache.abdera.factory.Factory;
-import org.apache.abdera.model.Base;
 import org.apache.abdera.model.Element;
-import org.apache.abdera.parser.stax.FOMExtensionFactory;
-import org.apache.axiom.om.OMContainer;
-import org.apache.axiom.om.OMFactory;
-import org.apache.axiom.om.OMXMLParserWrapper;
 
 public class ThreadExtensionFactory 
-  implements ExtensionFactory,
-    FOMExtensionFactory {
+  implements ExtensionFactory {
 
   public boolean handlesNamespace(String namespace) {
     return (ThreadConstants.THR_NS.equals(namespace));
@@ -47,42 +39,15 @@
   }
 
   @SuppressWarnings("unchecked")
-  public <T extends Element> T newExtensionElement(
-    QName qname,
-    Base parent, 
-    Factory factory) {
-      if (ThreadConstants.IN_REPLY_TO.equals(qname)) 
-        return (T)new FOMInReplyTo(
-          qname, 
-          (OMContainer)parent, 
-          (OMFactory)factory);
-      else if (ThreadConstants.THRTOTAL.equals(qname))
-        return (T)new FOMTotal(
-          qname, 
-          (OMContainer)parent, 
-          (OMFactory)factory);
-      else return null;
+  public <T extends Element> T getElementWrapper(Element internal) {
+    QName qname = internal.getQName();
+    if (ThreadConstants.IN_REPLY_TO.equals(qname)) 
+      return (T)new InReplyToImpl(internal);
+    else if (ThreadConstants.THRTOTAL.equals(qname))
+      return (T)new TotalImpl(internal);
+    else return (T)internal;
   }
 
-  @SuppressWarnings("unchecked")
-  public <T extends Element> T newExtensionElement(
-    QName qname,
-    Base parent, 
-    Factory factory, 
-    OMXMLParserWrapper parserWrapper) {
-      if (ThreadConstants.IN_REPLY_TO.equals(qname)) 
-        return (T)new FOMInReplyTo(
-          qname, 
-          (OMContainer)parent, 
-          (OMFactory)factory,
-          parserWrapper);
-      else if (ThreadConstants.THRTOTAL.equals(qname))
-        return (T)new FOMTotal(
-          qname, 
-          (OMContainer)parent, 
-          (OMFactory)factory,
-          parserWrapper);
-      else return null;
-  }
+
 
 }

Modified: incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/thread/ThreadHelper.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/thread/ThreadHelper.java?view=diff&rev=469180&r1=469179&r2=469180
==============================================================================
--- incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/thread/ThreadHelper.java (original)
+++ incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/thread/ThreadHelper.java Mon Oct 30 08:26:18 2006
@@ -24,8 +24,6 @@
 import javax.activation.MimeType;
 import javax.activation.MimeTypeParseException;
 
-import org.apache.abdera.ext.thread.impl.FOMInReplyTo;
-import org.apache.abdera.ext.thread.impl.FOMTotal;
 import org.apache.abdera.factory.Factory;
 import org.apache.abdera.model.AtomDate;
 import org.apache.abdera.model.Entry;
@@ -110,11 +108,7 @@
   }
   
   public static InReplyTo addInReplyTo(Entry entry) {
-    Factory factory = entry.getFactory();
-    InReplyTo replyTo = 
-      (InReplyTo) factory.newExtensionElement(
-        ThreadConstants.IN_REPLY_TO, entry);
-    return replyTo;
+    return entry.addExtension(ThreadConstants.IN_REPLY_TO);
   }
 
   public static InReplyTo addInReplyTo(Entry entry, Entry ref) {
@@ -193,12 +187,12 @@
     return list;
   }
 
-  public static InReplyTo newInReplyTo() {
-    return new FOMInReplyTo();
+  public static InReplyTo newInReplyTo(Factory factory) {
+    return new InReplyToImpl(factory);
   }
   
-  public static Total newTotal() {
-    return new FOMTotal();
+  public static Total newTotal(Factory factory) {
+    return new TotalImpl(factory);
   }
   
 }

Added: incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/thread/TotalImpl.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/thread/TotalImpl.java?view=auto&rev=469180
==============================================================================
--- incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/thread/TotalImpl.java (added)
+++ incubator/abdera/java/trunk/extensions/src/main/java/org/apache/abdera/ext/thread/TotalImpl.java Mon Oct 30 08:26:18 2006
@@ -0,0 +1,45 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  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.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.ext.thread;
+
+import org.apache.abdera.factory.Factory;
+import org.apache.abdera.model.Element;
+import org.apache.abdera.model.ElementWrapper;
+
+public class TotalImpl 
+  extends ElementWrapper 
+  implements Total {
+
+  public TotalImpl(Element internal) {
+    super(internal);
+  }
+
+  public TotalImpl(Factory factory) {
+    super(factory, ThreadConstants.THRTOTAL);
+  }
+
+  public int getValue() {
+    String val = getText();
+    return (val != null) ? Integer.parseInt(val) : -1;
+  }
+
+  public void setValue(int value) {
+    setText(String.valueOf(value));
+  }
+
+}

Modified: incubator/abdera/java/trunk/extensions/src/test/java/org/apache/abdera/test/ext/opensearch/OpenSearchTest.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/extensions/src/test/java/org/apache/abdera/test/ext/opensearch/OpenSearchTest.java?view=diff&rev=469180&r1=469179&r2=469180
==============================================================================
--- incubator/abdera/java/trunk/extensions/src/test/java/org/apache/abdera/test/ext/opensearch/OpenSearchTest.java (original)
+++ incubator/abdera/java/trunk/extensions/src/test/java/org/apache/abdera/test/ext/opensearch/OpenSearchTest.java Mon Oct 30 08:26:18 2006
@@ -25,10 +25,8 @@
 
 import org.apache.abdera.parser.Parser;
 
-import org.apache.abdera.ext.opensearch.TotalResults;
+import org.apache.abdera.ext.opensearch.IntegerElement;
 import org.apache.abdera.ext.opensearch.OpenSearchConstants;
-import org.apache.abdera.ext.opensearch.ItemsPerPage;
-import org.apache.abdera.ext.opensearch.StartIndex;
 
 import java.io.InputStream;
 
@@ -40,16 +38,16 @@
     InputStream stream = OpenSearchTest.class.getResourceAsStream("/opensearch.xml");
     Document<Element> doc = parser.parse(stream);
 
-    TotalResults tr = doc.getRoot().getFirstChild(OpenSearchConstants.TOTAL_RESULTS);
+    IntegerElement tr = doc.getRoot().getFirstChild(OpenSearchConstants.TOTAL_RESULTS_V10);
     assertNotNull(tr);
-    assertEquals(tr.getCount(), 47);
+    assertEquals(tr.getValue(), 47);
 
-    ItemsPerPage ipp = doc.getRoot().getFirstChild(OpenSearchConstants.ITEMS_PER_PAGE);
+    IntegerElement ipp = doc.getRoot().getFirstChild(OpenSearchConstants.ITEMS_PER_PAGE_V10);
     assertNotNull(ipp);
-    assertEquals(ipp.getCount(), 1);
+    assertEquals(ipp.getValue(), 1);
 
-    StartIndex si = doc.getRoot().getFirstChild(OpenSearchConstants.START_INDEX);
+    IntegerElement si = doc.getRoot().getFirstChild(OpenSearchConstants.START_INDEX_V10);
     assertNotNull(si);
-    assertEquals(si.getIndex(), 1);
+    assertEquals(si.getValue(), 1);
   }
 }

Modified: incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/FOMDocument.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/FOMDocument.java?view=diff&rev=469180&r1=469179&r2=469180
==============================================================================
--- incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/FOMDocument.java (original)
+++ incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/FOMDocument.java Mon Oct 30 08:26:18 2006
@@ -30,6 +30,7 @@
 import org.apache.abdera.factory.Factory;
 import org.apache.abdera.model.Document;
 import org.apache.abdera.model.Element;
+import org.apache.abdera.model.ElementWrapper;
 import org.apache.abdera.util.iri.IRI;
 import org.apache.abdera.util.iri.IRISyntaxException;
 import org.apache.axiom.om.OMComment;
@@ -90,11 +91,16 @@
 
   @SuppressWarnings("unchecked")
   public T getRoot() {  
-    return (T)this.getOMDocumentElement();
+    FOMFactory factory = (FOMFactory) getFactory();
+    return factory.getElementWrapper((T)this.getOMDocumentElement());
   }
 
   public void setRoot(T root) {
-    this.setOMDocumentElement((OMElement) root);
+    if (root instanceof OMElement) {
+      this.setOMDocumentElement((OMElement) root);
+    } else if (root instanceof ElementWrapper) {
+      this.setOMDocumentElement((OMElement) ((ElementWrapper)root).getInternal());
+    }
   }
 
   public IRI getBaseUri() {

Modified: incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/FOMElement.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/FOMElement.java?view=diff&rev=469180&r1=469179&r2=469180
==============================================================================
--- incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/FOMElement.java (original)
+++ incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/FOMElement.java Mon Oct 30 08:26:18 2006
@@ -39,11 +39,13 @@
 import org.apache.abdera.model.Div;
 import org.apache.abdera.model.Document;
 import org.apache.abdera.model.Element;
+import org.apache.abdera.model.ElementWrapper;
 import org.apache.abdera.model.Link;
 import org.apache.abdera.model.Text;
 import org.apache.abdera.parser.ParseException;
 import org.apache.abdera.parser.Parser;
 import org.apache.abdera.parser.ParserOptions;
+import org.apache.abdera.parser.stax.util.FOMElementIteratorWrapper;
 import org.apache.abdera.parser.stax.util.FOMList;
 import org.apache.abdera.util.Constants;
 import org.apache.abdera.util.MimeTypeHelper;
@@ -114,9 +116,16 @@
         factory);
   }
   
+  protected Element getWrapped(Element internal) {
+    FOMFactory factory = (FOMFactory) getFactory();
+    return factory.getElementWrapper(internal);
+  }
+  
   @SuppressWarnings("unchecked")
   public <T extends Base>T getParentElement() {
-    return (T)super.getParent();
+    T parent = (T)super.getParent();
+    return (T) ((parent instanceof Element) ? 
+      getWrapped((Element)parent) : parent);
   }
   
   protected void setParentDocument(Document parent) {
@@ -124,6 +133,9 @@
   }
   
   public void setParentElement(Element parent) {
+    if (parent instanceof ElementWrapper) {
+      parent = ((ElementWrapper)parent).getInternal();
+    }
     super.setParent((FOMElement)parent);
   }
 
@@ -131,7 +143,7 @@
   public <T extends Element>T getPreviousSibling() {
     OMNode el = this.getPreviousOMSibling();
     while (el != null) {
-      if (el instanceof Element) return (T)el;
+      if (el instanceof Element) return (T)getWrapped((Element)el);
       else el = el.getPreviousOMSibling();
     }
     return null;
@@ -141,7 +153,7 @@
   public <T extends Element>T getNextSibling() {
     OMNode el = this.getNextOMSibling();
     while (el != null) {
-      if (el instanceof Element) return (T) el;
+      if (el instanceof Element) return (T)getWrapped((Element)el);
       else el = el.getNextOMSibling();
     }
     return null;
@@ -149,7 +161,7 @@
   
   @SuppressWarnings("unchecked")
   public <T extends Element>T getFirstChild() {
-    return (T)this.getFirstElement();
+    return (T)getWrapped((Element)this.getFirstElement());
   }
   
   @SuppressWarnings("unchecked")
@@ -158,7 +170,7 @@
     while (el != null) {
       OMElement omel = (OMElement) el;
       if (omel.getQName().equals(qname))
-        return (T)omel;
+        return (T)getWrapped((Element)omel);
       el = el.getPreviousSibling();
     }
     return null;
@@ -170,7 +182,7 @@
     while (el != null) {
       OMElement omel = (OMElement) el;
       if (omel.getQName().equals(qname))
-        return (T)omel;
+        return (T)getWrapped((Element)omel);
       el = el.getNextSibling();
     }
     return null;
@@ -178,7 +190,7 @@
   
   @SuppressWarnings("unchecked")
   public <T extends Element>T getFirstChild(QName qname) {
-    return (T)this.getFirstChildWithName(qname);
+    return (T)getWrapped((Element)this.getFirstChildWithName(qname));
   }
   
   public String getLanguage() {
@@ -261,7 +273,9 @@
   
   @SuppressWarnings("unchecked")
   protected <E extends Element>List<E> _getChildrenAsSet(QName qname) {
-    return new FOMList(getChildrenWithName(qname));
+    FOMFactory factory = (FOMFactory) getFactory();
+    return new FOMList(new FOMElementIteratorWrapper(
+      factory,getChildrenWithName(qname)));
   }
   
   protected void _setChild(QName qname, OMElement element) {
@@ -612,6 +626,6 @@
   }
   
   public void declareNS(String prefix, String uri) {
-    super.declareNamespace(prefix,uri);
+    super.declareNamespace(uri,prefix);
   }
 }

Modified: incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/FOMExtensibleElement.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/FOMExtensibleElement.java?view=diff&rev=469180&r1=469179&r2=469180
==============================================================================
--- incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/FOMExtensibleElement.java (original)
+++ incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/FOMExtensibleElement.java Mon Oct 30 08:26:18 2006
@@ -22,7 +22,9 @@
 import javax.xml.namespace.QName;
 
 import org.apache.abdera.model.Element;
+import org.apache.abdera.model.ElementWrapper;
 import org.apache.abdera.model.ExtensibleElement;
+import org.apache.abdera.parser.stax.util.FOMElementIteratorWrapper;
 import org.apache.abdera.parser.stax.util.FOMExtensionIterator;
 import org.apache.abdera.parser.stax.util.FOMList;
 import org.apache.axiom.om.OMContainer;
@@ -80,26 +82,47 @@
 
   @SuppressWarnings("unchecked")
   public <T extends Element>List<T> getExtensions(QName qname) {
-    return new FOMList<T>(getChildrenWithName(qname));
+    FOMFactory factory = (FOMFactory) this.getFactory();
+    return new FOMList<T>(
+      new FOMElementIteratorWrapper(
+        factory,getChildrenWithName(qname)));
   }
 
   @SuppressWarnings("unchecked")
   public <T extends Element>T getExtension(QName qname) {
-    return (T) this.getFirstChildWithName(qname);
+    FOMFactory factory = (FOMFactory) getFactory();
+    T t = (T) this.getFirstChildWithName(qname);
+    return (T) ((t != null) ? factory.getElementWrapper(t) : null);
   }
   
   public void addExtension(Element extension) {
+    if (extension instanceof ElementWrapper) {
+      ElementWrapper wrapper = (ElementWrapper) extension;
+      extension = wrapper.getInternal();
+    }
+    QName qname = extension.getQName();
+    String prefix = qname.getPrefix();
+    if (prefix != null) {
+      declareNS(prefix, qname.getNamespaceURI());
+    }
     addChild((OMElement)extension);
   }
   
   @SuppressWarnings("unchecked")
   public <T extends Element>T addExtension(QName qname) {
     FOMFactory fomfactory = (FOMFactory) factory;
+    String prefix = qname.getPrefix();
+    if (prefix != null) {
+      declareNS(prefix, qname.getNamespaceURI());
+    }
     return (T)fomfactory.newExtensionElement(qname, this);
   }
   
   @SuppressWarnings("unchecked")
   public <T extends Element>T addExtension(String namespace, String localpart, String prefix) {
+    if (prefix != null) {
+      declareNS(prefix, namespace);
+    }
     return (T)addExtension(new QName(namespace, localpart, prefix));
   }
 
@@ -107,6 +130,10 @@
     FOMFactory fomfactory = (FOMFactory) factory;
     Element el = fomfactory.newElement(qname, this);
     el.setText(value);
+    String prefix = qname.getPrefix();
+    if (prefix != null) {
+      declareNS(prefix, qname.getNamespaceURI());
+    }
     return el;
   }
   
@@ -115,6 +142,9 @@
     String localPart, 
     String prefix, 
     String value) {
+      if (prefix != null) {
+        declareNS(prefix, namespace);
+      }
       return addSimpleExtension(
         new QName(
           namespace, 

Modified: incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/FOMFactory.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/FOMFactory.java?view=diff&rev=469180&r1=469179&r2=469180
==============================================================================
--- incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/FOMFactory.java (original)
+++ incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/FOMFactory.java Mon Oct 30 08:26:18 2006
@@ -18,10 +18,7 @@
 package org.apache.abdera.parser.stax;
  
 import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 import javax.activation.MimeType;
 import javax.activation.MimeTypeParseException;
@@ -29,6 +26,7 @@
 
 import org.apache.abdera.Abdera;
 import org.apache.abdera.factory.ExtensionFactory;
+import org.apache.abdera.factory.ExtensionFactoryMap;
 import org.apache.abdera.factory.Factory;
 import org.apache.abdera.model.Base;
 import org.apache.abdera.model.Categories;
@@ -67,22 +65,21 @@
 
 public class FOMFactory 
   extends OMLinkedListImplFactory 
-  implements Factory, Constants, ExtensionFactory, FOMExtensionFactory {
+  implements Factory, Constants, ExtensionFactory {
 
-  private final Map<QName,Class> extensions;
-  private final List<ExtensionFactory> factories;
+  private final ExtensionFactoryMap factoriesMap;
   
   public FOMFactory() {
     this(new Abdera());
   }
   
   public FOMFactory(Abdera abdera) {
-    List<ExtensionFactory> f= abdera.getConfiguration().getExtensionFactories();
-    this.factories = (f != null) ? 
-      new ArrayList<ExtensionFactory>(f) :
-      new ArrayList<ExtensionFactory>();
-    this.factories.add(this);
-    this.extensions = Collections.synchronizedMap(new HashMap<QName,Class>());
+    List<ExtensionFactory> f= 
+      abdera.getConfiguration().getExtensionFactories();
+    factoriesMap = new ExtensionFactoryMap(
+      (f != null) ? 
+        new ArrayList<ExtensionFactory>(f) :
+        new ArrayList<ExtensionFactory>());
   }
   
   public Parser newParser() {
@@ -404,11 +401,11 @@
   public Element newElement(
     QName qname, 
     Base parent) {
-      return new FOMExtensibleElement(qname, (OMContainer)parent,this);
+      return newExtensionElement(qname, parent);
   }
   
   public Element newExtensionElement(QName qname) {
-    return newExtensionElement(qname, (Base)null);
+    return newExtensionElement(qname, (OMContainer)null);
   }
   
   public Element newExtensionElement(
@@ -420,11 +417,14 @@
   private Element newExtensionElement(
     QName qname, 
     OMContainer parent) {
-      return newExtensionElement(qname, parent, null);
+      String ns = qname.getNamespaceURI();
+      Element el = newExtensionElement(qname, parent, null);
+      return (ATOM_NS.equals(ns) || APP_NS.equals(ns)) ?
+        el : factoriesMap.getElementWrapper(el);
   }
 
   private List<ExtensionFactory> getExtensionFactories() {
-    return factories;
+    return factoriesMap.getFactories();
   }
   
   @SuppressWarnings("unchecked")
@@ -432,27 +432,11 @@
     QName qname,
     OMContainer parent,
     OMXMLParserWrapper parserWrapper) {
-    Element element = null;
-    List<ExtensionFactory> factories = getExtensionFactories();
-    for (ExtensionFactory factory : factories) {
-      if (factory instanceof FOMExtensionFactory &&
-        factory.handlesNamespace(qname.getNamespaceURI())) {
-        if (parserWrapper != null) {
-          element = ((FOMExtensionFactory)factory).newExtensionElement(
-            qname, (Base)parent, this, parserWrapper);
-        } else {
-          element = factory.newExtensionElement(qname, (Base)parent, this); 
-        }
-      }
-    }
-    if (element == null) {
-      if (parserWrapper == null) {
-        element = new FOMExtensibleElement(qname, parent, this);
-      } else {
-        element = new FOMExtensibleElement(qname, parent, this, parserWrapper);
-      }
-    }
-    return element;
+    Element element = (parserWrapper == null) ?
+      new FOMExtensibleElement(qname, parent, this) :
+      new FOMExtensibleElement(qname, parent, this, parserWrapper);
+    //return factoriesMap.getElementWrapper(element);
+      return element;
   }
   
   public Control newControl() {
@@ -711,7 +695,9 @@
         element = new FOMDateTime(qname.getLocalPart(), namespace, parent, factory);
       } else if (parent instanceof ExtensibleElement || 
                  parent instanceof Document) {
-        element = (OMElement) newExtensionElement(qname, parent);
+        //element = (OMElement) newExtensionElement(qname, parent);
+        element = (OMElement) new FOMExtensibleElement(
+          qname.getLocalPart(), namespace, parent, this);
       }
       return element;
     }
@@ -784,79 +770,16 @@
     } else if (EDITED.equals(qname)) {
       element = (OMElement) newDateTimeElement(qname, parent, builder);
     } else if (parent instanceof ExtensibleElement || parent instanceof Document) {
-      element = (OMElement) newExtensionElement(qname, parent, builder);
+      //element = (OMElement) newExtensionElement(qname, parent, builder);
+      element = (OMElement) new FOMExtensibleElement(qname, parent, this,builder);
     }
     return element;
   }
 
-  public void registerExtension(QName qname, Class impl) {
-    extensions.put(qname, impl);
-  }
-  
   public void registerExtension(ExtensionFactory factory) {
     getExtensionFactories().add(factory);
   }
 
-  public List<String> getNamespaces() {
-    List<String> namespaces = new ArrayList<String>();
-    for (QName qname : extensions.keySet()) {
-      if (!namespaces.contains(qname.getNamespaceURI()))
-        namespaces.add(qname.getNamespaceURI());
-    }
-    return namespaces;
-  }
-
-  public boolean handlesNamespace(String namespace) {
-    return getNamespaces().contains(namespace);
-  }
-
-  @SuppressWarnings("unchecked")
-  public <T extends Element> T newExtensionElement(
-    QName qname, 
-    Base parent, 
-    Factory factory) {
-      Class _class = extensions.get(qname);
-      if (_class != null) {
-        try {
-          return (T)_class.getConstructor(
-            new Class[] {
-              QName.class,
-              OMContainer.class,
-              OMFactory.class}).newInstance(
-                new Object[] {
-                  qname, 
-                  parent, 
-                  factory});
-        } catch (Exception e) {}
-      }
-      return null;
-  }
-
-  @SuppressWarnings("unchecked")
-  public <T extends Element> T newExtensionElement(
-    QName qname, 
-    Base parent, 
-    Factory factory, 
-    OMXMLParserWrapper parserWrapper) {
-      Class _class = extensions.get(qname);
-      if (_class != null) {
-        try {
-          return (T)_class.getConstructor(
-            new Class[] {
-              QName.class,
-              OMContainer.class,
-              OMFactory.class,
-              OMXMLParserWrapper.class}).newInstance(
-                new Object[] {
-                  qname, 
-                  parent, 
-                  factory,
-                  parserWrapper});
-        } catch (Exception e) {}
-      }
-      return null;
-  }
-
   public Categories newCategories() {
     Document<Categories> doc = newDocument();
     return newCategories(doc);
@@ -876,4 +799,27 @@
   public String newUuidUri() {
     return FOMHelper.generateUuid();
   }
+
+  public void setElementWrapper(Element internal, Element wrapper) {
+    factoriesMap.setElementWrapper(internal, wrapper);
+  }
+  
+  @SuppressWarnings("unchecked")
+  public <T extends Element> T getElementWrapper(Element internal) {
+    String ns = internal.getQName().getNamespaceURI();
+    return (T) ((ATOM_NS.equals(ns) || 
+                 APP_NS.equals(ns) || 
+                 internal.getQName().equals(DIV)) ?
+      internal :
+      factoriesMap.getElementWrapper(internal));
+  }
+
+  public List<String> getNamespaces() {
+    return factoriesMap.getNamespaces();
+  }
+
+  public boolean handlesNamespace(String namespace) {
+    return factoriesMap.handlesNamespace(namespace);
+  }
+
 }

Added: incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMElementIteratorWrapper.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMElementIteratorWrapper.java?view=auto&rev=469180
==============================================================================
--- incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMElementIteratorWrapper.java (added)
+++ incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMElementIteratorWrapper.java Mon Oct 30 08:26:18 2006
@@ -0,0 +1,47 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  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.  For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+package org.apache.abdera.parser.stax.util;
+
+import java.util.Iterator;
+
+import org.apache.abdera.model.Element;
+import org.apache.abdera.parser.stax.FOMFactory;
+
+public class FOMElementIteratorWrapper implements Iterator {
+
+  private final Iterator iterator;
+  private final FOMFactory factory;
+  
+  public FOMElementIteratorWrapper(FOMFactory factory, Iterator iterator) {
+    this.iterator = iterator;
+    this.factory = factory;
+  }
+  
+  public boolean hasNext() {
+    return iterator.hasNext();
+  }
+
+  public Object next() {
+    return factory.getElementWrapper((Element) iterator.next());
+  }
+
+  public void remove() {
+    iterator.remove();
+  }
+
+}

Modified: incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMExtensionIterator.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMExtensionIterator.java?view=diff&rev=469180&r1=469179&r2=469180
==============================================================================
--- incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMExtensionIterator.java (original)
+++ incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMExtensionIterator.java Mon Oct 30 08:26:18 2006
@@ -17,6 +17,8 @@
 */
 package org.apache.abdera.parser.stax.util;
 
+import org.apache.abdera.model.Element;
+import org.apache.abdera.parser.stax.FOMFactory;
 import org.apache.axiom.om.OMElement;
 import org.apache.axiom.om.impl.traverse.OMChildrenIterator;
 
@@ -33,6 +35,7 @@
    */
   private String namespace = null;
   private String extns = null;
+  private FOMFactory factory = null;
 
   /**
    * Field needToMoveForward
@@ -53,6 +56,7 @@
   public FOMExtensionIterator(OMElement parent) {
     super(parent.getFirstOMChild());
     this.namespace = parent.getQName().getNamespaceURI();
+    this.factory = (FOMFactory) parent.getOMFactory();
   }
   
   public FOMExtensionIterator(OMElement parent, String extns) {
@@ -101,7 +105,7 @@
       removeCalled = false;
       lastChild = currentChild;
       currentChild = currentChild.getNextOMSibling();
-      return lastChild;
+      return factory.getElementWrapper((Element)lastChild);
   }
 
   private boolean isQNamesMatch(QName elementQName, String namespace) {

Modified: incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMList.java
URL: http://svn.apache.org/viewvc/incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMList.java?view=diff&rev=469180&r1=469179&r2=469180
==============================================================================
--- incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMList.java (original)
+++ incubator/abdera/java/trunk/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMList.java Mon Oct 30 08:26:18 2006
@@ -46,8 +46,8 @@
   extends java.util.AbstractCollection<T>
   implements List<T> {
 
-  private Iterator<T> i = null;
-  private List<T> buffer = new ArrayList<T>();
+  private final Iterator<T> i;
+  private final List<T> buffer = new ArrayList<T>();
   
   public FOMList(Iterator<T> i) {
     this.i = i;