Ok, so I've spent some time this morning implementing a way of
separating extensions from the underlying Axiom implementation. The
mechanism is surprisingly simple. I haven't checked this in yet but
will do so if no one cries Stop!
I've attached the patch for review.
To create an extension element, a developer would extend either
ElementWrapper or ExtensibleElementWrapper.
public class FooElement extends ElementWrapper {
protected FooElement(Element internal) {
super(internal);
}
protected FooElement(Factory factory) {
super(factory, TestExtensionFactory.FOO);
}
public String getFoo() {
return getText();
}
public void setFoo(String foo) {
setText(foo);
}
}
Then register an ExtensionFactory like before, but the methods have
changed a bit:
public class TestExtensionFactory implements ExtensionFactory {
public static final QName FOO = new QName("urn:foo", "foo");
@SuppressWarnings("unchecked")
public <T extends Element> T getElementWrapper(Element internal) {
QName qname = internal.getQName();
if (qname.equals(FOO)) return (T)new FooElement(internal);
return (T) internal;
}
public List<String> getNamespaces() {
return java.util.Arrays.asList(new String[] {"urn:foo"});
}
public boolean handlesNamespace(String namespace) {
return namespace.equals("urn:foo");
}
}
We can then use FooElement seamlessly with the core API
Abdera abdera = new Abdera();
Factory factory = abdera.getFactory();
factory.registerExtension(new TestExtensionFactory());
Entry entry = factory.newEntry();
FooElement foo = entry.addExtension(TestExtensionFactory.FOO);
foo.setFoo("testing");
Or...
Abdera abdera = new Abdera();
Factory factory = abdera.getFactory();
factory.registerExtension(new TestExtensionFactory());
String s = "<foo xmlns='urn:foo'>testing</foo>";
ByteArrayInputStream in = new ByteArrayInputStream(s.getBytes());
Parser parser = abdera.getParser();
ParserOptions options = parser.getDefaultParserOptions();
options.setFactory(factory);
Document<FooElement> doc = parser.parse(in, null, options);
FooElement foo = doc.getRoot();
System.out.println(foo.getFoo());
Thoughts?
- James
Index:
/home/jasnell/workspaces/abdera/core/src/main/java/org/apache/abdera/factory/ExtensionFactory.java
===================================================================
---
/home/jasnell/workspaces/abdera/core/src/main/java/org/apache/abdera/factory/ExtensionFactory.java
(revision 467053)
+++
/home/jasnell/workspaces/abdera/core/src/main/java/org/apache/abdera/factory/ExtensionFactory.java
(working copy)
@@ -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
@@ -67,16 +64,5 @@
*/
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
- */
- <T extends Element>T newExtensionElement(QName qname, Base parent, Factory
factory);
-
+ <T extends Element>T getElementWrapper(Element internal);
}
Index:
/home/jasnell/workspaces/abdera/core/src/main/java/org/apache/abdera/factory/ExtensionFactoryMap.java
===================================================================
---
/home/jasnell/workspaces/abdera/core/src/main/java/org/apache/abdera/factory/ExtensionFactoryMap.java
(revision 0)
+++
/home/jasnell/workspaces/abdera/core/src/main/java/org/apache/abdera/factory/ExtensionFactoryMap.java
(revision 0)
@@ -0,0 +1,86 @@
+/*
+* 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.HashMap;
+
+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 HashMap<Element,Element>();
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T extends Element> T getElementWrapper(Element internal) {
+ T t = (T)wrappers.get(internal);
+ if (t == null) {
+ for (ExtensionFactory factory : factories) {
+ t = factory.getElementWrapper(internal);
+ if (t != null) {
+ 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;
+ }
+}
Index:
/home/jasnell/workspaces/abdera/core/src/main/java/org/apache/abdera/factory/Factory.java
===================================================================
---
/home/jasnell/workspaces/abdera/core/src/main/java/org/apache/abdera/factory/Factory.java
(revision 467053)
+++
/home/jasnell/workspaces/abdera/core/src/main/java/org/apache/abdera/factory/Factory.java
(working copy)
@@ -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);
}
Index:
/home/jasnell/workspaces/abdera/core/src/main/java/org/apache/abdera/model/ElementWrapper.java
===================================================================
---
/home/jasnell/workspaces/abdera/core/src/main/java/org/apache/abdera/model/ElementWrapper.java
(revision 0)
+++
/home/jasnell/workspaces/abdera/core/src/main/java/org/apache/abdera/model/ElementWrapper.java
(revision 0)
@@ -0,0 +1,202 @@
+/*
+* 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 final 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 {
+ return super.clone();
+ } 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;
+ }
+}
Index:
/home/jasnell/workspaces/abdera/core/src/main/java/org/apache/abdera/model/ExtensibleElementWrapper.java
===================================================================
---
/home/jasnell/workspaces/abdera/core/src/main/java/org/apache/abdera/model/ExtensibleElementWrapper.java
(revision 0)
+++
/home/jasnell/workspaces/abdera/core/src/main/java/org/apache/abdera/model/ExtensibleElementWrapper.java
(revision 0)
@@ -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);
+ }
+
+}
Index:
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/FOMDocument.java
===================================================================
---
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/FOMDocument.java
(revision 467052)
+++
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/FOMDocument.java
(working copy)
@@ -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() {
Index:
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/FOMExtensibleElement.java
===================================================================
---
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/FOMExtensibleElement.java
(revision 467052)
+++
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/FOMExtensibleElement.java
(working copy)
@@ -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,7 +82,10 @@
@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")
@@ -85,10 +90,16 @@
@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();
+ }
addChild((OMElement)extension);
}
Index:
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/FOMExtensionFactory.java
===================================================================
---
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/FOMExtensionFactory.java
(revision 467052)
+++
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/FOMExtensionFactory.java
(working copy)
@@ -1,37 +0,0 @@
-/*
-* 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;
-
-import javax.xml.namespace.QName;
-
-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.axiom.om.OMXMLParserWrapper;
-
-
-public interface FOMExtensionFactory extends ExtensionFactory {
-
- public <T extends Element>T newExtensionElement(
- QName qname,
- Base parent,
- Factory factory,
- OMXMLParserWrapper parserWrapper);
-
-}
Index:
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/FOMFactory.java
===================================================================
---
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/FOMFactory.java
(revision 467052)
+++
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/FOMFactory.java
(working copy)
@@ -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,10 +65,9 @@
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());
@@ -77,12 +74,12 @@
}
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,7 +770,8 @@
} 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;
}
@@ -789,10 +776,6 @@
return element;
}
- public void registerExtension(QName qname, Class impl) {
- extensions.put(qname, impl);
- }
-
public void registerExtension(ExtensionFactory factory) {
getExtensionFactories().add(factory);
}
@@ -797,66 +780,6 @@
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);
+ }
+
}
Index:
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMElementIteratorWrapper.java
===================================================================
---
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMElementIteratorWrapper.java
(revision 0)
+++
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMElementIteratorWrapper.java
(revision 0)
@@ -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();
+ }
+
+}
Index:
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMExtensionIterator.java
===================================================================
---
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMExtensionIterator.java
(revision 467052)
+++
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMExtensionIterator.java
(working copy)
@@ -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) {
Index:
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMList.java
===================================================================
---
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMList.java
(revision 467052)
+++
/home/jasnell/workspaces/abdera/parser/src/main/java/org/apache/abdera/parser/stax/util/FOMList.java
(working copy)
@@ -24,6 +24,8 @@
import java.util.List;
import java.util.ListIterator;
+import org.apache.abdera.parser.stax.FOMFactory;
+
/**
* Implements an ElementSet around an internal buffered iterator.
* Here's the rationale:
@@ -46,8 +48,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;