protected Document readPropertyValue()

in modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/BaseAssemblyProcessor.java [447:564]


    protected Document readPropertyValue(QName element, QName type, boolean isMany, XMLStreamReader reader, ProcessorContext context) throws XMLStreamException,
        ContributionReadException {
        Document document;
        try {
            if (documentBuilderFactory == null) {
                documentBuilderFactory = DocumentBuilderFactory.newInstance();
                documentBuilderFactory.setNamespaceAware(true);
            }
            document = documentBuilderFactory.newDocumentBuilder().newDocument();
        } catch (ParserConfigurationException e) {
            ContributionReadException ce = new ContributionReadException(e);
            error(context.getMonitor(), "ContributionReadException", documentBuilderFactory, ce);
            throw ce;
        }

        // Collect the property values as <value> elements under the <property>
        Element root = document.createElementNS(SCA11_NS, "sca:" + PROPERTY);
        String nameAttr = getString(reader, NAME);
        if (nameAttr != null) {
            root.setAttributeNS(SCA11_NS, "sca:" + NAME, nameAttr);
        }
        declareNamespace(root, "sca", SCA11_NS);
        if (type != null) {
            org.w3c.dom.Attr xsi = document.createAttributeNS(XMLNS_ATTRIBUTE_NS_URI, "xmlns:xsi");
            xsi.setValue(W3C_XML_SCHEMA_INSTANCE_NS_URI);
            root.setAttributeNodeNS(xsi);

            String prefix = type.getPrefix();
            if (prefix == null || prefix.length() == 0) {
                prefix = "ns";
            }

            declareNamespace(root, prefix, type.getNamespaceURI());

            org.w3c.dom.Attr xsiType = document.createAttributeNS(W3C_XML_SCHEMA_INSTANCE_NS_URI, "xsi:type");
            xsiType.setValue(prefix + ":" + type.getLocalPart());
            root.setAttributeNodeNS(xsiType);
        }
        document.appendChild(root);

        // Start to parse the property
        QName name = reader.getName(); // Should be sca:property

        // SCA 1.1 supports the @value for simple types
        String valueAttr = getString(reader, VALUE);
        if (valueAttr != null) {
            Element valueElement = document.createElementNS(SCA11_NS, VALUE);
            root.appendChild(valueElement);
            valueElement.setTextContent(valueAttr);
        }

        boolean gotOneValue = false;
        boolean isTextForProperty = true;
        StringBuffer text = new StringBuffer();

        int event = reader.getEventType();
        while (true) {
            switch (event) {
                case START_ELEMENT:
                    name = reader.getName();
                    if (PROPERTY_QNAME.equals(name)) {
                        isTextForProperty = true;
                        break;
                    }
                    isTextForProperty = false;
                    
                    // CONFORMANCE: ASM50033
                    // A property <value/> subelement MUST NOT be used when the @value attribute is used 
                    // to specify the value for that property.
                    if (valueAttr != null) {
                        error(context.getMonitor(), "ValueAttributeForPropertyElement", element, nameAttr);
                    }
                    // Read <value>
                    if (VALUE_QNAME.equals(name)) {
                    	if (gotOneValue && !isMany) {
                    	    // TODO: TUSCANY-3231 this should be error not warning but that breaks OASIS tests
                    	    // [rfeng] We should not issue warning here as the component property many inherit @many from the componentType property
                    	    // warning(context.getMonitor(), "ASM50032: multiple value elements for single-valued property", name, name);
                    	}
                        loadElement(reader, root);
                        gotOneValue = true;
                    } else {
                        // Global elements
                        loadElement(reader, root);
                    }
                    break;
                case XMLStreamConstants.CHARACTERS:
                case XMLStreamConstants.CDATA:
                    if (isTextForProperty) {
                        text.append(reader.getText());
                    }
                    break;
                case END_ELEMENT:
                    name = reader.getName();
                    if (PROPERTY_QNAME.equals(name)) {
                        
                        if (root.getChildNodes().getLength() == 0) {
                            // Add an text as an <value>
                            if (isTextForProperty){
                                if (text.length() > 0) {
                                    Element valueElement = document.createElementNS(SCA11_NS, VALUE);
                                    root.appendChild(valueElement);
                                    valueElement.setTextContent(text.toString());
                                }
                            }
                        }
                        return document;
                    }
                    break;
            }
            if (reader.hasNext()) {
                event = reader.next();
            } else {
                break;
            }
        }
        return document;
    }