You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by oz...@apache.org on 2009/11/12 18:17:13 UTC
svn commit: r835455 -
/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/Parser.java
Author: ozzy
Date: Thu Nov 12 17:17:13 2009
New Revision: 835455
URL: http://svn.apache.org/viewvc?rev=835455&view=rev
Log:
ARIES-46 Update parser to invoke namespace handler for custom scope values. Requires updated blueprint schema to declare custom scopes. Fixes attribute-only custom namespace usage, fixes processing of namespace declaration attributes.
Modified:
incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/Parser.java
Modified: incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/Parser.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/Parser.java?rev=835455&r1=835454&r2=835455&view=diff
==============================================================================
--- incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/Parser.java (original)
+++ incubator/aries/trunk/blueprint/blueprint-core/src/main/java/org/apache/aries/blueprint/container/Parser.java Thu Nov 12 17:17:13 2009
@@ -30,22 +30,13 @@
import java.util.Set;
import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.validation.Schema;
import javax.xml.validation.Validator;
-import org.w3c.dom.Attr;
-import org.w3c.dom.CharacterData;
-import org.w3c.dom.Comment;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.EntityReference;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
import org.apache.aries.blueprint.ComponentDefinitionRegistry;
import org.apache.aries.blueprint.NamespaceHandler;
import org.apache.aries.blueprint.reflect.BeanArgumentImpl;
@@ -89,6 +80,15 @@
import org.osgi.service.blueprint.reflect.ValueMetadata;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.w3c.dom.Attr;
+import org.w3c.dom.CharacterData;
+import org.w3c.dom.Comment;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.EntityReference;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
/**
@@ -234,8 +234,26 @@
private void findNamespaces(Set<URI> namespaces, Node node) {
if (node instanceof Element || node instanceof Attr) {
String ns = node.getNamespaceURI();
- if (ns != null && !isBlueprintNamespace(ns)) {
+ if (ns != null && !isBlueprintNamespace(ns) && !XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(ns)) {
namespaces.add(URI.create(ns));
+ }else if ( ns == null && //attributes from blueprint are unqualified as per schema.
+ node instanceof Attr &&
+ SCOPE_ATTRIBUTE.equals(node.getNodeName()) &&
+ ((Attr)node).getOwnerElement() != null && //should never occur from parsed doc.
+ BLUEPRINT_NAMESPACE.equals(((Attr)node).getOwnerElement().getNamespaceURI()) &&
+ BEAN_ELEMENT.equals(((Attr)node).getOwnerElement().getLocalName()) ){
+ //Scope attribute is special case, as may contain namespace usage within its value.
+
+ URI scopeNS = getNamespaceForAttributeValue(node);
+ if(scopeNS!=null){
+ namespaces.add(scopeNS);
+ }
+ }
+ }
+ NamedNodeMap nnm = node.getAttributes();
+ if(nnm!=null){
+ for(int i = 0; i< nnm.getLength() ; i++){
+ findNamespaces(namespaces, nnm.item(i));
}
}
NodeList nl = node.getChildNodes();
@@ -405,6 +423,61 @@
}
}
}
+
+ /**
+ * Takes an Attribute Node containing a namespace prefix qualified attribute value, and resolves the namespace using the DOM Node.<br>
+ *
+ * @param attr The DOM Node with the qualified attribute value.
+ * @return The URI if one is resolvable, or null if the attr is null, or not namespace prefixed. (or not a DOM Attribute Node)
+ * @throws ComponentDefinitonException if the namespace prefix in the attribute value cannot be resolved.
+ */
+ private URI getNamespaceForAttributeValue(Node attrNode){
+ URI uri = null;
+ if(attrNode!=null && (attrNode instanceof Attr)){
+ Attr attr = (Attr)attrNode;
+ String attrValue = attr.getValue();
+ if(attrValue!=null && attrValue.indexOf(":")!=-1){
+ String parts[] = attrValue.split(":");
+ String uriStr = attr.getOwnerElement().lookupNamespaceURI(parts[0]);
+ if(uriStr!=null){
+ uri = URI.create(uriStr);
+ }else{
+ throw new ComponentDefinitionException("Unsupported attribute namespace prefix "+parts[0]+" "+attr);
+ }
+ }
+ }
+ return uri;
+ }
+
+ /**
+ * Tests if a scope attribute value is a custom scope, and if so invokes
+ * the appropriate namespace handler, passing the blueprint scope node.
+ * <p>
+ * Currently this tests for custom scope by looking for the presence of
+ * a ':' char within the scope attribute value. This is valid as long as
+ * the blueprint schema continues to restrict that custom scopes should
+ * require that characters presence.
+ * <p>
+ *
+ * @param scope Value of scope attribute
+ * @param bean DOM element for bean associated to this scope
+ * @param cm Metadata for bean associated to this scope
+ * @return Metadata as processed by NS Handler.
+ * @throws ComponentDefinitionException if an undeclared prefix is used,
+ * if a namespace handler is unavailable for a resolved prefix,
+ * or if the resolved prefix results as the blueprint namespace.
+ */
+ private ComponentMetadata handleCustomScope(Node scope, Element bean, ComponentMetadata metadata){
+ URI scopeNS = getNamespaceForAttributeValue(scope);
+ if(scopeNS!=null && !BLUEPRINT_NAMESPACE.equals(scopeNS)){
+ NamespaceHandler nsHandler = getNamespaceHandler(scopeNS);
+ ParserContextImpl context = new ParserContextImpl(this, registry, metadata, scope);
+ metadata = nsHandler.decorate(scope, metadata, context);
+ }else if(scopeNS!=null){
+ throw new ComponentDefinitionException("Custom scopes cannot use the blueprint namespace "+scope);
+ }
+ return metadata;
+ }
private ComponentMetadata parseBeanMetadata(Element element, boolean topElement) {
BeanMetadataImpl metadata = new BeanMetadataImpl();
@@ -478,7 +551,10 @@
MetadataUtil.validateBeanArguments(metadata.getArguments());
ComponentMetadata m = metadata;
-
+
+ // Parse custom scopes
+ m = handleCustomScope(element.getAttributeNode(SCOPE_ATTRIBUTE), element, m);
+
// Parse custom attributes
m = handleCustomAttributes(element.getAttributes(), m);
@@ -1114,9 +1190,12 @@
if (attributes != null) {
for (int i = 0; i < attributes.getLength(); i++) {
Node node = attributes.item(i);
+ //attr is custom if it has a namespace, and it isnt blueprint, or the xmlns ns.
+ //blueprint ns would be an error, as blueprint attrs are unqualified.
if (node instanceof Attr &&
node.getNamespaceURI() != null &&
- !isBlueprintNamespace(node.getNamespaceURI())) {
+ !isBlueprintNamespace(node.getNamespaceURI()) &&
+ !XMLConstants.XMLNS_ATTRIBUTE_NS_URI.equals(node.getNamespaceURI()) ) {
enclosingComponent = decorateCustomNode(node, enclosingComponent);
}
}
@@ -1150,17 +1229,22 @@
}
private NamespaceHandler getNamespaceHandler(Node node) {
+ URI ns = URI.create(node.getNamespaceURI());
+ NamespaceHandler handler = getNamespaceHandler(ns);
+ return handler;
+ }
+
+ private NamespaceHandler getNamespaceHandler(URI uri) {
if (handlers == null) {
- throw new ComponentDefinitionException("Unsupported node (namespace handler registry is not set): " + node);
+ throw new ComponentDefinitionException("Unsupported node (namespace handler registry is not set): " + uri);
}
- URI ns = URI.create(node.getNamespaceURI());
- NamespaceHandler handler = this.handlers.getNamespaceHandler(ns);
+ NamespaceHandler handler = this.handlers.getNamespaceHandler(uri);
if (handler == null) {
- throw new ComponentDefinitionException("Unsupported node namespace: " + node.getNamespaceURI());
+ throw new ComponentDefinitionException("Unsupported node namespace: " + uri);
}
return handler;
}
-
+
public String getId(Element element) {
String id;
if (element.hasAttribute(ID_ATTRIBUTE)) {