Example usage for org.dom4j Element attributes

List of usage examples for org.dom4j Element attributes

Introduction

In this page you can find the example usage for org.dom4j Element attributes.

Prototype

List<Attribute> attributes();

Source Link

Document

Returns the Attribute instances this element contains as a backed List so that the attributes may be modified directly using the List interface.

Usage

From source file:org.orbeon.oxf.transformer.xupdate.TemplatesHandlerImpl.java

License:Open Source License

private Statement[] parseStatements(List nodes) {
    List statements = new ArrayList();
    for (Iterator i = nodes.iterator(); i.hasNext();) {
        Node node = (Node) i.next();
        if (node.getNodeType() == Node.TEXT_NODE) {
            if (!"".equals(node.getText().trim()))
                statements.add(new Text(node.getText().trim()));
        } else if (node.getNodeType() == Node.ELEMENT_NODE) {
            Element element = (Element) node;
            NamespaceContext namespaceContext = new SimpleNamespaceContext(
                    Dom4jUtils.getNamespaceContext(element));
            if (XUpdateConstants.XUPDATE_NAMESPACE_URI.equals(element.getNamespaceURI())) {
                if (element.getName().equals("remove")) {
                    statements.add(new Remove((LocationData) element.getData(),
                            element.attributeValue("select"), namespaceContext));
                } else if (element.getName().equals("update")) {
                    statements/*from www.j  a v a 2  s. co m*/
                            .add(new Update((LocationData) element.getData(), element.attributeValue("select"),
                                    namespaceContext, parseStatements(element.content())));
                } else if (element.getName().equals("append")) {
                    statements.add(new Append((LocationData) element.getData(),
                            element.attributeValue("select"), namespaceContext, element.attributeValue("child"),
                            parseStatements(element.content())));
                } else if (element.getName().equals("insert-before")) {
                    statements.add(
                            new InsertBefore((LocationData) element.getData(), element.attributeValue("select"),
                                    namespaceContext, parseStatements(element.content())));
                } else if (element.getName().equals("insert-after")) {
                    statements.add(
                            new InsertAfter((LocationData) element.getData(), element.attributeValue("select"),
                                    namespaceContext, parseStatements(element.content())));
                } else if (element.getName().equals("for-each")) {
                    statements
                            .add(new ForEach((LocationData) element.getData(), element.attributeValue("select"),
                                    namespaceContext, parseStatements(element.content())));
                } else if (element.getName().equals("while")) {
                    statements.add(new While((LocationData) element.getData(), element.attributeValue("select"),
                            namespaceContext, parseStatements(element.content())));
                } else if (element.getName().equals("value-of")) {
                    statements.add(new ValueOf((LocationData) element.getData(),
                            element.attributeValue("select"), namespaceContext));
                } else if (element.getName().equals("copy-of")) {
                    statements.add(new CopyOf((LocationData) element.getData(),
                            element.attributeValue("select"), namespaceContext));
                } else if (element.getName().equals("node-set")) {
                    statements.add(new NodeSet((LocationData) element.getData(),
                            element.attributeValue("select"), namespaceContext));
                } else if (element.getName().equals("attribute")) {
                    statements.add(new Attribute((LocationData) element.getData(), parseQName(element),
                            parseStatements(element.content())));
                } else if (element.getName().equals("namespace")) {
                    statements.add(new Namespace((LocationData) element.getData(),
                            element.attributeValue("name"), element.attributeValue("select"), namespaceContext,
                            parseStatements(element.content())));
                } else if (element.getName().equals("element")) {
                    statements.add(new DynamicElement((LocationData) element.getData(), parseQName(element),
                            parseStatements(element.content())));
                } else if (element.getName().equals("if")) {
                    statements.add(new If((LocationData) element.getData(), element.attributeValue("test"),
                            namespaceContext, parseStatements(element.content())));
                } else if (element.getName().equals("choose")) {
                    List whenTests = new ArrayList();
                    List whenNamespaceContext = new ArrayList();
                    List whenStatements = new ArrayList();
                    for (Iterator j = element.elements("when").iterator(); j.hasNext();) {
                        Element whenElement = (Element) j.next();
                        whenTests.add(whenElement.attributeValue("test"));
                        whenNamespaceContext
                                .add(new SimpleNamespaceContext(Dom4jUtils.getNamespaceContext(whenElement)));
                        whenStatements.add(parseStatements(whenElement.content()));
                    }
                    Element otherwiseElement = element.element("otherwise");
                    statements.add(new Choose((LocationData) element.getData(),
                            (String[]) whenTests.toArray(new String[whenTests.size()]),
                            (NamespaceContext[]) whenNamespaceContext
                                    .toArray(new NamespaceContext[whenNamespaceContext.size()]),
                            (Statement[][]) whenStatements.toArray(new Statement[whenStatements.size()][]),
                            otherwiseElement == null ? null : parseStatements(otherwiseElement.content())));
                } else if (element.getName().equals("variable")) {
                    statements.add(new Variable((LocationData) element.getData(), parseQName(element),
                            element.attributeValue("select"), namespaceContext,
                            parseStatements(element.content())));
                } else if (element.getName().equals("assign")) {
                    statements.add(new Assign((LocationData) element.getData(), parseQName(element),
                            element.attributeValue("select"), namespaceContext,
                            parseStatements(element.content())));
                } else if (element.getName().equals("function")) {
                    statements.add(new Function((LocationData) element.getData(), parseQName(element),
                            parseStatements(element.content())));
                } else if (element.getName().equals("param")) {
                    statements.add(new Param((LocationData) element.getData(), parseQName(element),
                            element.attributeValue("select"), namespaceContext,
                            parseStatements(element.content())));
                } else if (element.getName().equals("message")) {
                    statements.add(
                            new Message((LocationData) element.getData(), parseStatements(element.content())));
                } else if (element.getName().equals("error")) {
                    statements.add(
                            new Error((LocationData) element.getData(), parseStatements(element.content())));
                } else {
                    throw new ValidationException(
                            "Unsupported XUpdate element '" + element.getQualifiedName() + "'",
                            (LocationData) element.getData());
                }
            } else {
                Element staticElement = new NonLazyUserDataElement(element.getQName());
                List childNodes = new ArrayList();
                for (Iterator j = element.attributes().iterator(); j.hasNext();)
                    staticElement.add((org.dom4j.Attribute) ((org.dom4j.Attribute) j.next()).clone());
                for (Iterator j = element.content().iterator(); j.hasNext();) {
                    Node child = (Node) j.next();
                    if (child instanceof org.dom4j.Namespace) {
                        staticElement.add((Node) child.clone());
                    } else {
                        childNodes.add(child);
                    }
                }
                statements.add(new StaticElement((LocationData) element.getData(), staticElement,
                        parseStatements(childNodes)));
            }
        } else if (node.getNodeType() == Node.NAMESPACE_NODE) {
            // Ignore namespace declarations
        } else {
            throw new OXFException("Unsupported node: " + node.getNodeTypeName());
        }
    }
    return (Statement[]) statements.toArray(new Statement[statements.size()]);
}

From source file:org.orbeon.oxf.xforms.action.actions.XFormsDeleteAction.java

License:Open Source License

private static DeleteInfo doDeleteOne(IndentedLogger indentedLogger, List collectionToUpdate, int deleteIndex) {
    final NodeInfo nodeInfoToRemove = (NodeInfo) collectionToUpdate.get(deleteIndex - 1);
    final NodeInfo parentNodeInfo = nodeInfoToRemove.getParent();

    final Node nodeToRemove = XFormsUtils.getNodeFromNodeInfo(nodeInfoToRemove, CANNOT_DELETE_READONLY_MESSAGE);

    final List contentToUpdate;
    final int indexInContentToUpdate;
    final Element parentElement = nodeToRemove.getParent();
    if (parentElement != null) {
        // Regular case
        if (nodeToRemove instanceof Attribute) {
            contentToUpdate = parentElement.attributes();
        } else {// ww  w. j av  a 2  s .  com
            contentToUpdate = parentElement.content();
        }
        indexInContentToUpdate = contentToUpdate.indexOf(nodeToRemove);
    } else if (nodeToRemove.getDocument() != null
            && nodeToRemove == nodeToRemove.getDocument().getRootElement()) {
        // Case of root element where parent is Document
        contentToUpdate = nodeToRemove.getDocument().content();
        indexInContentToUpdate = contentToUpdate.indexOf(nodeToRemove);
    } else if (nodeToRemove instanceof Document) {
        // Case where node to remove is Document

        // "except if the node is the root document element of an instance then the delete action
        // is terminated with no effect."

        if (indentedLogger.isDebugEnabled())
            indentedLogger.logDebug("xf:delete", "ignoring attempt to delete document node");

        return null;
    } else {
        // Node to remove doesn't have a parent so we can't delete it
        // This can happen for nodes already detached, or nodes newly created with e.g. xf:element()
        return null;
    }

    // Actually perform the deletion
    // "The node at the delete location in the Node Set Binding node-set is deleted"
    contentToUpdate.remove(indexInContentToUpdate);

    return new DeleteInfo(parentNodeInfo, nodeInfoToRemove, indexInContentToUpdate);
}

From source file:org.orbeon.oxf.xforms.InstanceData.java

License:Open Source License

public static <A extends Node> A remove(A node) {

    // We can't store data on the Document object. Use root element instead.
    Node adjustedNode = node;//from w w  w  .  j a v a2s  .  co  m
    if (node instanceof Document)
        adjustedNode = ((Document) node).getRootElement();

    if (adjustedNode instanceof Element) {
        final Element element = (Element) adjustedNode;

        // Handle current element
        element.setData(null);

        // Handle attributes
        for (Object o : element.attributes()) {
            final Attribute attribute = (Attribute) o;
            remove(attribute);
        }
        // Handle children elements
        for (Object o : element.elements()) {
            final Element childElement = (Element) o;
            remove(childElement);
        }

    } else if (adjustedNode instanceof Attribute) {
        ((Attribute) adjustedNode).setData(null);
    } else {
        // TODO: other node types once we update to handling text nodes correctly. But it looks like Text does not support data.
    }

    return node;
}

From source file:org.orbeon.oxf.xforms.XFormsModelSchemaValidator.java

License:Open Source License

private boolean validateElement(final Element element, final Acceptor acceptor, final IDConstraintChecker icc,
        final boolean isReportErrors) {

    boolean isElementValid = true;

    // Create StartTagInfo
    final StartTagInfo startTagInfo;
    {// w ww . jav  a  2 s  .c  o  m
        final String uri = element.getNamespaceURI();
        final String name = element.getName();
        final String qName = element.getQualifiedName();
        final List attributesList = element.attributes();
        final AttributesImpl attributes = new AttributesImpl();

        for (Object anAttributesList : attributesList) {
            final Attribute attribute = (Attribute) anAttributesList;
            final String attributeURI = attribute.getNamespaceURI();
            final String attributeName = attribute.getName();
            final String attributeQName = attribute.getQualifiedName();
            final String attributeValue = attribute.getValue();
            attributes.addAttribute(attributeURI, attributeName, attributeQName, null, attributeValue);
        }
        validationContext.setCurrentElement(element);
        startTagInfo = new StartTagInfo(uri, name, qName, attributes, validationContext);
    }

    final StringRef stringRef = new StringRef();

    // Get child acceptor
    final Acceptor childAcceptor;
    {
        Acceptor tempChildAcceptor = acceptor.createChildAcceptor(startTagInfo, null);
        if (tempChildAcceptor == null) {
            if (isReportErrors) {
                tempChildAcceptor = acceptor.createChildAcceptor(startTagInfo, stringRef);
                addSchemaError(element, stringRef.str);
                isElementValid = false;
            } else {
                return false;
            }
        }
        childAcceptor = tempChildAcceptor;
    }

    // Handle id errors
    if (icc != null && isReportErrors) {
        icc.onNextAcceptorReady(startTagInfo, childAcceptor, element);
        isElementValid &= handleIDErrors(icc);
    }

    // Validate children
    final DatatypeRef datatypeRef = new DatatypeRef();
    final boolean childrenValid = validateChildren(element, childAcceptor, startTagInfo, icc, datatypeRef,
            isReportErrors);
    if (!childrenValid) {
        if (isReportErrors)
            isElementValid = false;
        else
            return false;
    }

    // TODO: MSV doesn't allow getting the type if validity check fails. However, we would like to obtain datatype validity in XForms.
    if (!childAcceptor.isAcceptState(null)) {
        if (isReportErrors) {
            childAcceptor.isAcceptState(stringRef);
            addSchemaError(element, stringRef.str);
            isElementValid = false;
        } else {
            return false;
        }
    } else {
        // Attempt to set datatype name
        setDataType(datatypeRef, element);
    }

    // Handle id errors
    if (icc != null && isReportErrors) {
        icc.endElement(element, datatypeRef.types);
        isElementValid &= handleIDErrors(icc);
    }

    // Get back to parent acceptor
    if (!acceptor.stepForward(childAcceptor, null)) {
        if (isReportErrors) {
            acceptor.stepForward(childAcceptor, stringRef);
            addSchemaError(element, stringRef.str);
            isElementValid = false;
        } else {
            return false;
        }
    }

    if (isReportErrors) {
        // Element may be invalid or not
        return isElementValid;
    } else {
        // This element is valid
        return true;
    }
}

From source file:org.orbeon.oxf.xforms.XFormsModelSchemaValidator.java

License:Open Source License

/**
 * Validate an element following the XML Schema "lax" mode.
 *
 * @param element   element to validate//from  w  w w. j  av  a 2  s.c o m
 */
private boolean validateElementLax(final Element element) {

    final String elementURI;
    final String elementName;

    // NOTE: We do some special processing for xsi:type to find if there is a type declared for it. If not, we do
    // lax processing. However, it is not clear whether we should apply lax processing in this case or not. Maybe if
    // an xsi:type is specified and not found, the element should just be invalid.
    // TODO: should pass true?
    final QName xsiType = Dom4jUtils.extractAttributeValueQName(element, XMLConstants.XSI_TYPE_QNAME, false);
    if (xsiType != null) {
        // Honor xsi:type
        elementURI = xsiType.getNamespaceURI();
        elementName = xsiType.getName();
    } else {
        // Use element name
        elementURI = element.getNamespaceURI();
        elementName = element.getName();
    }

    boolean isValid = true;
    {
        // Find expression for element type
        final Expression expression;
        {
            // Find schema for type namespace
            final XMLSchemaSchema schema = ((XMLSchemaGrammar) schemaGrammar).getByNamespace(elementURI);
            if (schema != null) {
                // Try to find the expression in the schema
                final ElementDeclExp elementDeclExp = schema.elementDecls.get(elementName);
                if (elementDeclExp != null) {
                    // Found element type
                    expression = elementDeclExp;
                } else if (xsiType != null) {
                    // Try also complex type
                    expression = schema.complexTypes.get(elementName);
                } else {
                    // No type found
                    expression = null;
                }
            } else {
                // No schema so no expression
                expression = null;
            }
        }

        if (expression != null) {
            // Found type for element, so validate element
            final Acceptor acceptor = documentDeclaration.createAcceptor();
            isValid &= validateElement(element, acceptor, null, true);
        } else {
            // Element does not have type, so try to validate attributes and children elements

            // Attributes
            if (false) {
                // TODO: find out way of validating an attribute only
                // TODO: should we also look at schema.attributeGroups?
                final List attributesList = element.attributes();
                for (final Iterator iterator = attributesList.iterator(); iterator.hasNext();) {
                    final Attribute attribute = (Attribute) iterator.next();
                    final String attributeURI = attribute.getNamespaceURI();
                    final String attributeName = attribute.getName();
                    //                        final String attributeQName = attribute.getQualifiedName();
                    //                        final String attributeValue = attribute.getValue();

                    // Find expression for element type
                    final Expression attributeExpression;
                    {
                        // Find schema for type namespace
                        final XMLSchemaSchema schema = ((XMLSchemaGrammar) schemaGrammar)
                                .getByNamespace(attributeURI);
                        if (schema != null) {
                            attributeExpression = schema.attributeDecls.get(attributeName);
                        } else {
                            attributeExpression = null;
                        }
                    }
                    if (attributeExpression != null) {
                        //                            final ExpressionAcceptor expressionAcceptor = new SimpleAcceptor(documentDeclaration, attributeExpression, null, null);
                        //                            // Validate attribute value
                        //                            final StringRef errorStringRef = new StringRef();
                        //                            final DatatypeRef datatypeRef = new DatatypeRef();
                        //
                        //                            if (!expressionAcceptor.onAttribute2(attributeURI, attributeName, attributeQName, attributeValue, validationContext, errorStringRef, datatypeRef)) {
                        //                                if (errorStringRef.str == null) // not sure if this can happen
                        //                                    errorStringRef.str = "Error validating attribute";
                        //                                addSchemaError(attribute, errorStringRef.str);
                        //                            }

                        //                            if (!expressionAcceptor.onText2(attributeValue, validationContext, errorStringRef, datatypeRef)) {
                        //                                if (errorStringRef.str == null) // not sure if this can happen
                        //                                    errorStringRef.str = "Error validating attribute";
                        //                                addSchemaError(attribute, errorStringRef.str);
                        //                            }
                        //
                        //                            // Check final acceptor state
                        //                            if (!expressionAcceptor.isAcceptState(errorStringRef)) {
                        //                                if (errorStringRef.str == null) // not sure if this can happen
                        //                                    errorStringRef.str = "Error validating attribute";
                        //                                addSchemaError(attribute, errorStringRef.str);
                        //                            }
                    }
                }
            }

            // Validate children elements
            for (final Iterator iterator = element.elementIterator(); iterator.hasNext();) {
                final Element childElement = (Element) iterator.next();
                isValid &= validateElementLax(childElement);
            }
        }
    }
    return isValid;
}

From source file:org.orbeon.oxf.xml.dom4j.Dom4jUtils.java

License:Open Source License

/**
 * Typed version of the dom4j API.//  ww  w .  j a  v  a  2 s.com
 */
@SuppressWarnings("unchecked")
public static List<Attribute> attributes(Element element) {
    return (List<Attribute>) element.attributes();
}

From source file:org.pentaho.di.ui.trans.steps.getxmldata.GetXMLDataDialog.java

License:Open Source License

@SuppressWarnings("unchecked")
private void setNodeField(Node node, String realXPathCleaned) {
    Element e = (Element) node;
    // get all attributes
    List<Attribute> lista = e.attributes();
    for (int i = 0; i < lista.size(); i++) {
        setAttributeField(lista.get(i), realXPathCleaned);
    }//from  w  ww . j  a  v a  2 s.  c  o m

    // Get Node Name
    String nodename = node.getName();
    String nodenametxt = cleanString(node.getPath(), realXPathCleaned);

    if (!Const.isEmpty(nodenametxt) && !list.contains(nodenametxt)) {
        TableItem item = new TableItem(wFields.table, SWT.NONE);
        item.setText(1, nodename);
        item.setText(2, nodenametxt);
        item.setText(3, GetXMLDataField.ElementTypeDesc[0]);

        // Get Node value
        String valueNode = node.getText();

        // Try to get the Type
        if (IsDate(valueNode)) {
            item.setText(4, "Date");
            item.setText(5, "yyyy/MM/dd");
        } else if (IsInteger(valueNode))
            item.setText(4, "Integer");
        else if (IsNumber(valueNode))
            item.setText(4, "Number");
        else
            item.setText(4, "String");

        list.add(nodenametxt);

    } // end if
}

From source file:org.pentaho.di.ui.trans.steps.getxmldata.XMLInputFieldsImportProgressDialog.java

License:Apache License

@SuppressWarnings("unchecked")
private void setNodeField(Node node, IProgressMonitor monitor) {
    Element e = (Element) node;
    // get all attributes
    List<Attribute> lista = e.attributes();
    for (int i = 0; i < lista.size(); i++) {
        setAttributeField(lista.get(i), monitor);
    }// w  ww  .ja  va2 s  . c  o m

    // Get Node Name
    String nodename = node.getName();
    String nodenametxt = cleanString(node.getPath());

    if (!Utils.isEmpty(nodenametxt) && !list.contains(nodenametxt)) {
        nr++;
        monitor.subTask(BaseMessages.getString(PKG,
                "GetXMLDataXMLInputFieldsImportProgressDialog.Task.FetchFields", String.valueOf(nr)));
        monitor.subTask(BaseMessages.getString(PKG,
                "GetXMLDataXMLInputFieldsImportProgressDialog.Task.AddingField", nodename));

        RowMetaAndData row = new RowMetaAndData();
        row.addValue(VALUE_NAME, Value.VALUE_TYPE_STRING, nodename);
        row.addValue(VALUE_PATH, Value.VALUE_TYPE_STRING, nodenametxt);
        row.addValue(VALUE_ELEMENT, Value.VALUE_TYPE_STRING, GetXMLDataField.ElementTypeDesc[0]);
        row.addValue(VALUE_RESULT, Value.VALUE_TYPE_STRING, GetXMLDataField.ResultTypeDesc[0]);

        // Get Node value
        String valueNode = node.getText();

        // Try to get the Type

        if (IsDate(valueNode)) {
            row.addValue(VALUE_TYPE, Value.VALUE_TYPE_STRING, "Date");
            row.addValue(VALUE_FORMAT, Value.VALUE_TYPE_STRING, "yyyy/MM/dd");
        } else if (IsInteger(valueNode)) {
            row.addValue(VALUE_TYPE, Value.VALUE_TYPE_STRING, "Integer");
            row.addValue(VALUE_FORMAT, Value.VALUE_TYPE_STRING, null);
        } else if (IsNumber(valueNode)) {
            row.addValue(VALUE_TYPE, Value.VALUE_TYPE_STRING, "Number");
            row.addValue(VALUE_FORMAT, Value.VALUE_TYPE_STRING, null);
        } else {
            row.addValue(VALUE_TYPE, Value.VALUE_TYPE_STRING, "String");
            row.addValue(VALUE_FORMAT, Value.VALUE_TYPE_STRING, null);
        }
        fieldsList.add(row);
        list.add(nodenametxt);

    } // end if
}

From source file:org.pentaho.jfreereport.wizard.utility.report.ReportGenerationUtility.java

License:Open Source License

/**
 * NOTE: the templateDoc is the target of the merge.
 * //from w w  w .j  a v  a  2s.c  o m
 * @param templateDoc
 * @param generatedDoc
 * @param mergeStream
 */
public static void mergeTemplate(Document templateDoc, Document generatedDoc, OutputStream mergeStream) {
    try {
        // replace parser-config settings in templateDoc from generatedDoc
        Element templateReportNode = ((Element) templateDoc.selectSingleNode("/report")); //$NON-NLS-1$
        Element generatedReportNode = ((Element) generatedDoc.selectSingleNode("/report")); //$NON-NLS-1$
        // move attributes from generated to template
        // blow away existing attributes first
        List templateAttributes = templateReportNode.attributes();
        for (int i = templateAttributes.size() - 1; i >= 0; i--) {
            Attribute attribute = (Attribute) templateAttributes.get(i);
            templateReportNode.remove(attribute);
        }
        // now move generated into template
        List generatedAttributes = generatedReportNode.attributes();
        for (int i = generatedAttributes.size() - 1; i >= 0; i--) {
            Attribute attribute = (Attribute) generatedAttributes.get(i);
            generatedReportNode.remove(attribute);
            templateReportNode.add(attribute);
        }
        List templateParserConfigProps = templateReportNode.selectNodes("parser-config/*"); //$NON-NLS-1$
        List generatedParserConfigProps = generatedReportNode.selectNodes("parser-config/*"); //$NON-NLS-1$
        Element templateParserConfigElement = (Element) templateReportNode.selectSingleNode("parser-config"); //$NON-NLS-1$
        Element generatedParserConfigElement = (Element) generatedReportNode.selectSingleNode("parser-config"); //$NON-NLS-1$
        // replace any empty elements in the generated doc with the corresponding contents of the template doc 
        for (int i = 0; i < generatedParserConfigProps.size(); i++) {
            Element generatedParserConfigProp = (Element) generatedParserConfigProps.get(i);
            Element templateParserConfigProp = (Element) templateParserConfigProps.get(i);

            String generatedText = generatedParserConfigProp.getText();
            if (!StringUtils.isEmpty(generatedText)) {
                generatedParserConfigElement.remove(generatedParserConfigProp);
                templateParserConfigElement.remove(templateParserConfigProp);
                templateParserConfigElement.add(generatedParserConfigProp);
            }
        }

        // replace items section in templateDoc from generatedDoc
        if (templateReportNode.selectSingleNode("items") != null) { //$NON-NLS-1$
            templateReportNode.remove(templateReportNode.selectSingleNode("items")); //$NON-NLS-1$
        }
        Element itemsElement = (Element) generatedReportNode.selectSingleNode("items"); //$NON-NLS-1$
        if (itemsElement != null) {
            generatedReportNode.remove(itemsElement);
            templateReportNode.add(itemsElement);
        }
        // GROUP MERGING
        List groups = templateReportNode.selectNodes("groups/*"); //$NON-NLS-1$
        // if groups has no elements, then we're just going to straight copy
        // the groups from the generated version
        // this is a new requirement per Kurtis Cruzada
        if (ReportSpecUtility.getNumberOfGroupsInTemplate(templateDoc) == 0) {
            // replace groups section in templateDoc from generatedDoc
            if (templateReportNode.selectSingleNode("groups") != null) { //$NON-NLS-1$
                templateReportNode.remove(templateReportNode.selectSingleNode("groups")); //$NON-NLS-1$
            }
            // might not have a top level groups node, add it
            if (generatedReportNode.selectSingleNode("groups") == null) { //$NON-NLS-1$
                generatedReportNode.addElement("groups"); //$NON-NLS-1$
            }
            Element groupElement = (Element) generatedReportNode.selectSingleNode("groups"); //$NON-NLS-1$
            if (groupElement != null) {
                generatedReportNode.remove(groupElement);
                templateReportNode.add(groupElement);
            }
        } else {
            // both sets of groups should be identical in number
            // each group based on index should correspond
            // for all group headers, append new content
            // for all group footers insert new content, push down old
            // both lists must have the same # of groups (this is a
            // requirement)
            List generatedGroups = generatedReportNode.selectNodes("groups/*"); //$NON-NLS-1$
            for (int i = 0; i < groups.size(); i++) {
                Element templateGroup = (Element) groups.get(i);
                for (int j = i + 1; j < generatedGroups.size(); j++) {
                    Element generatedGroup = (Element) generatedGroups.get(j);
                    Element templateGroupHeader = (Element) templateGroup.selectSingleNode("groupheader"); //$NON-NLS-1$
                    Element generatedGroupHeader = (Element) generatedGroup.selectSingleNode("groupheader"); //$NON-NLS-1$
                    Element templateGroupFooter = (Element) templateGroup.selectSingleNode("groupfooter"); //$NON-NLS-1$
                    Element generatedGroupFooter = (Element) generatedGroup.selectSingleNode("groupfooter"); //$NON-NLS-1$
                    try {
                        if (templateGroupHeader.attribute("pagebreak-before-print") != null) { //$NON-NLS-1$
                            templateGroupHeader.attribute("pagebreak-before-print").detach(); //$NON-NLS-1$
                        }
                        templateGroupHeader.addAttribute("pagebreak-before-print", //$NON-NLS-1$
                                (generatedGroupHeader.attributeValue("pagebreak-before-print")) + ""); //$NON-NLS-1$ //$NON-NLS-2$
                    } catch (Exception e) {
                        // e.printStackTrace();
                    }
                    try {
                        if (templateGroupHeader.attribute("pagebreak-after-print") != null) { //$NON-NLS-1$
                            templateGroupHeader.attribute("pagebreak-after-print").detach(); //$NON-NLS-1$
                        }
                        templateGroupHeader.addAttribute("pagebreak-after-print", //$NON-NLS-1$
                                (generatedGroupHeader.attributeValue("pagebreak-after-print")) + ""); //$NON-NLS-1$ //$NON-NLS-2$
                    } catch (Exception e) {
                        // e.printStackTrace();
                    }
                    try {
                        if (templateGroupFooter.attribute("pagebreak-before-print") != null) { //$NON-NLS-1$
                            templateGroupFooter.attribute("pagebreak-before-print").detach(); //$NON-NLS-1$
                        }
                        templateGroupFooter.addAttribute("pagebreak-before-print", //$NON-NLS-1$
                                (generatedGroupFooter.attributeValue("pagebreak-before-print")) + ""); //$NON-NLS-1$ //$NON-NLS-2$
                    } catch (Exception e) {
                        // e.printStackTrace();
                    }
                    try {
                        if (templateGroupFooter.attribute("pagebreak-after-print") != null) { //$NON-NLS-1$
                            templateGroupFooter.attribute("pagebreak-after-print").detach(); //$NON-NLS-1$
                        }
                        templateGroupFooter.addAttribute("pagebreak-after-print", //$NON-NLS-1$
                                (generatedGroupFooter.attributeValue("pagebreak-after-print")) + ""); //$NON-NLS-1$ //$NON-NLS-2$
                    } catch (Exception e) {
                        // e.printStackTrace();
                    }
                    try {
                        if (templateGroupHeader.attribute("repeat") != null) { //$NON-NLS-1$
                            templateGroupHeader.attribute("repeat").detach(); //$NON-NLS-1$
                        }
                        templateGroupHeader.addAttribute("repeat", //$NON-NLS-1$
                                (generatedGroupHeader.attributeValue("repeat")) + ""); //$NON-NLS-1$ //$NON-NLS-2$
                    } catch (Exception e) {
                        // e.printStackTrace();
                    }
                }
            }
            if (groups != null) {
                Element innermostGroup = null;
                int innermostFieldsInGroup = 0;
                for (int i = 0; i < groups.size(); i++) {
                    Element groupElement = (Element) groups.get(i);
                    List fields = groupElement.selectNodes("fields/*"); //$NON-NLS-1$
                    if (fields != null && fields.size() > 0 && fields.size() > innermostFieldsInGroup) {
                        innermostFieldsInGroup = fields.size();
                        innermostGroup = groupElement;
                    }
                }
                Element generatedInnermostGroup = null;
                if (generatedGroups != null) {
                    int generatedInnermostFieldsInGroup = 0;
                    for (int i = 0; i < generatedGroups.size(); i++) {
                        Element groupElement = (Element) generatedGroups.get(i);
                        List fields = groupElement.selectNodes("fields/*"); //$NON-NLS-1$
                        if (fields != null && fields.size() > 0
                                && fields.size() > generatedInnermostFieldsInGroup) {
                            generatedInnermostFieldsInGroup = fields.size();
                            generatedInnermostGroup = groupElement;
                        }
                    }
                }
                // at this point we have found the innermost group
                // this will be used for updating the group header/footer
                if (innermostGroup != null) {
                    // handle headers: append header if header exists, else
                    // create
                    Element groupHeader = (Element) innermostGroup.selectSingleNode("groupheader"); //$NON-NLS-1$
                    if (groupHeader == null) {
                        // direct header replacement with
                        // generatedInnermostGroup header
                        Element headerElement = (Element) generatedInnermostGroup
                                .selectSingleNode("groupheader"); //$NON-NLS-1$
                        if (headerElement != null) {
                            generatedInnermostGroup.remove(headerElement);
                            innermostGroup.add(headerElement);
                        }
                    } else {
                        // insertion: loop through elements of generated,
                        // append to header
                        List groupHeaderNodes = innermostGroup.selectNodes("groupheader/*"); //$NON-NLS-1$
                        List generatedGroupHeaderNodes = generatedInnermostGroup.selectNodes("groupheader/*"); //$NON-NLS-1$
                        Element generatedGroupHeader = (Element) generatedInnermostGroup
                                .selectSingleNode("groupheader"); //$NON-NLS-1$
                        // fix up header/footer breaking for innermost group
                        int y = 0;
                        for (int i = 0; i < groupHeaderNodes.size(); i++) {
                            Element element = (Element) groupHeaderNodes.get(i);
                            try {
                                y = Math.max(y, Integer.parseInt(element.attributeValue("y")) //$NON-NLS-1$
                                        + Integer.parseInt(element.attributeValue("height"))); //$NON-NLS-1$
                            } catch (Exception e) {
                                // NumberFormat exceptions, ignore
                            }
                            try {
                                y = Math.max(y, Integer.parseInt(element.attributeValue("y1")) //$NON-NLS-1$
                                        + Integer.parseInt(element.attributeValue("height"))); //$NON-NLS-1$
                            } catch (Exception e) {
                                // NumberFormat exceptions, ignore
                            }
                            try {
                                y = Math.max(y, Integer.parseInt(element.attributeValue("y2")) //$NON-NLS-1$
                                        + Integer.parseInt(element.attributeValue("height"))); //$NON-NLS-1$
                            } catch (Exception e) {
                                // NumberFormat exceptions, ignore
                            }
                        }
                        for (int i = 0; i < generatedGroupHeaderNodes.size(); i++) {
                            Element element = (Element) generatedGroupHeaderNodes.get(i);
                            generatedGroupHeader.remove(element);
                            if (element.attribute("y") != null) { //$NON-NLS-1$
                                int yValue = Integer.parseInt(element.attributeValue("y")); //$NON-NLS-1$
                                element.attribute("y").detach(); //$NON-NLS-1$
                                element.addAttribute("y", (y + yValue) + ""); //$NON-NLS-1$ //$NON-NLS-2$
                            } else if (element.attribute("y1") != null) { //$NON-NLS-1$
                                int yValue = Integer.parseInt(element.attributeValue("y1")); //$NON-NLS-1$
                                element.attribute("y1").detach(); //$NON-NLS-1$
                                element.addAttribute("y1", (y + yValue) + ""); //$NON-NLS-1$ //$NON-NLS-2$
                            } else if (element.attribute("y2") != null) { //$NON-NLS-1$
                                int yValue = Integer.parseInt(element.attributeValue("y2")); //$NON-NLS-1$
                                element.attribute("y2").detach(); //$NON-NLS-1$
                                element.addAttribute("y2", (y + yValue) + ""); //$NON-NLS-1$ //$NON-NLS-2$
                            }
                            groupHeader.add(element);
                        }
                    }
                    // handle footers:
                    Element groupFooter = (Element) innermostGroup.selectSingleNode("groupfooter"); //$NON-NLS-1$
                    if (groupFooter == null) {
                        // direct footer replacement with
                        // generatedInnermostGroup footer
                        Element footerElement = (Element) generatedInnermostGroup
                                .selectSingleNode("groupfooter"); //$NON-NLS-1$
                        if (footerElement != null) {
                            generatedInnermostGroup.remove(footerElement);
                            innermostGroup.add(footerElement);
                        }
                    } else {
                        // insertion: loop through elements of generated,
                        // inserting to
                        // template footer top (remove existing, add new,
                        // add existing back)
                        List groupFooterNodes = groupFooter.selectNodes("*"); //$NON-NLS-1$
                        // remove existing
                        for (int i = 0; i < groupFooterNodes.size(); i++) {
                            groupFooter.remove((Element) groupFooterNodes.get(i));
                        }
                        // add new
                        List generatedGroupFooterNodes = generatedInnermostGroup.selectNodes("groupfooter/*"); //$NON-NLS-1$
                        Element generatedGroupFooter = (Element) generatedInnermostGroup
                                .selectSingleNode("groupfooter"); //$NON-NLS-1$
                        int y = 0;
                        for (int i = 0; i < generatedGroupFooterNodes.size(); i++) {
                            Element element = (Element) generatedGroupFooterNodes.get(i);
                            generatedGroupFooter.remove(element);
                            groupFooter.add(element);
                            try {
                                y = Math.max(y, Integer.parseInt(element.attributeValue("y")) //$NON-NLS-1$
                                        + Integer.parseInt(element.attributeValue("height"))); //$NON-NLS-1$
                            } catch (Exception e) {
                                // NumberFormat exceptions, ignore
                            }
                            try {
                                y = Math.max(y, Integer.parseInt(element.attributeValue("y1")) //$NON-NLS-1$
                                        + Integer.parseInt(element.attributeValue("height"))); //$NON-NLS-1$
                            } catch (Exception e) {
                                // NumberFormat exceptions, ignore
                            }
                            try {
                                y = Math.max(y, Integer.parseInt(element.attributeValue("y2")) //$NON-NLS-1$
                                        + Integer.parseInt(element.attributeValue("height"))); //$NON-NLS-1$
                            } catch (Exception e) {
                                // NumberFormat exceptions, ignore
                            }
                        }
                        // add existing back, pushed down
                        for (int i = 0; i < groupFooterNodes.size(); i++) {
                            Element element = (Element) groupFooterNodes.get(i);
                            if (element.attribute("y") != null) { //$NON-NLS-1$
                                int yValue = Integer.parseInt(element.attributeValue("y")); //$NON-NLS-1$
                                element.attribute("y").detach(); //$NON-NLS-1$
                                element.addAttribute("y", (y + yValue) + ""); //$NON-NLS-1$ //$NON-NLS-2$
                            } else if (element.attribute("y1") != null) { //$NON-NLS-1$
                                int yValue = Integer.parseInt(element.attributeValue("y1")); //$NON-NLS-1$
                                element.attribute("y1").detach(); //$NON-NLS-1$
                                element.addAttribute("y1", (y + yValue) + ""); //$NON-NLS-1$ //$NON-NLS-2$
                            } else if (element.attribute("y2") != null) { //$NON-NLS-1$
                                int yValue = Integer.parseInt(element.attributeValue("y2")); //$NON-NLS-1$
                                element.attribute("y2").detach(); //$NON-NLS-1$
                                element.addAttribute("y2", (y + yValue) + ""); //$NON-NLS-1$ //$NON-NLS-2$
                            }
                            groupFooter.add((Element) groupFooterNodes.get(i));
                        }
                    }
                }
            }
            // need to merge 'dummy' group if we're doing grand totals
            for (int i = 0; i < generatedGroups.size(); i++) {
                Element generatedGroup = (Element) generatedGroups.get(i);
                if (generatedGroup.attributeValue(NAME_ATTRIBUTE_NAME).equals("dummy")) { //$NON-NLS-1$
                    for (int j = 0; j < groups.size(); j++) {
                        Element group = (Element) groups.get(j);
                        if (group.attributeValue(NAME_ATTRIBUTE_NAME).equals("dummy")) { //$NON-NLS-1$
                            Element groupsElement = (Element) templateReportNode.selectSingleNode("groups"); //$NON-NLS-1$
                            generatedGroup.detach();
                            group.detach();
                            groupsElement.add(generatedGroup);
                        }
                    }
                }
            }
        }
        // 'merge' functions section in templateDoc from generatedDoc
        Element functionsElement = (Element) templateReportNode.selectSingleNode("functions"); //$NON-NLS-1$
        Element generatedFunctionsElement = (Element) generatedReportNode.selectSingleNode("functions"); //$NON-NLS-1$
        if (generatedFunctionsElement != null) {
            List functionList = generatedFunctionsElement.selectNodes("function"); //$NON-NLS-1$
            for (int i = 0; i < functionList.size(); i++) {
                Element functionElement = (Element) functionList.get(i);
                generatedFunctionsElement.remove(functionElement);
                functionsElement.add(functionElement);
            }
        }
        // 'merge' expression section in templateDoc from generatedDoc
        Element expressionsElement = (Element) templateReportNode.selectSingleNode("functions"); //$NON-NLS-1$
        Element generatedExpressionsElement = (Element) generatedReportNode.selectSingleNode("functions"); //$NON-NLS-1$
        if (generatedExpressionsElement != null) {
            List expressionsList = generatedExpressionsElement.selectNodes("expression"); //$NON-NLS-1$
            for (int i = 0; i < expressionsList.size(); i++) {
                Element expressionElement = (Element) expressionsList.get(i);
                generatedExpressionsElement.remove(expressionElement);
                expressionsElement.add(expressionElement);
            }
        }
        // pump watermark if exists
        if (generatedReportNode.selectSingleNode("watermark") != null) { //$NON-NLS-1$
            Element watermarkNode = (Element) generatedReportNode.selectSingleNode("watermark"); //$NON-NLS-1$
            Element templateWatermarkNode = (Element) templateReportNode.selectSingleNode("watermark"); //$NON-NLS-1$
            if (templateWatermarkNode != null) {
                templateWatermarkNode.detach();
            }
            if (watermarkNode != null) {
                watermarkNode.detach();
            }
            templateReportNode.add(watermarkNode);
        }
        // push generatedDoc changes into templateDoc and write result to
        // mergeStream
        OutputFormat format = OutputFormat.createPrettyPrint();
        XMLWriter writer = new XMLWriter(mergeStream, format);
        writer.write(templateDoc);
        writer.close();
    } catch (Exception e) {
        getLogger().error(e.getMessage(), e);
    }
}

From source file:org.pentaho.platform.plugin.adhoc.AdhocContentGenerator.java

License:Open Source License

/**
 * Create the JFreeReport file.//from   w w  w  . j a v  a2s  .  com
 * 
 * NOTE on the merge precedence: this method should use properties set by the 
 * WAQR UI. If the waqr UI did not set the property, then the property 
 * should be set by the metadata. If the metadata did not set a property,
 * then the property should be set by the template. If the template
 * did not set the property, then use the default.
 * 
 * NOTE on the merge algorithm: 
 * For each of the attributes in the fields (aka columns) of the reportspec,
 * if the attribute is present in the reportspec that comes in from the client
 * (ie reportXML param), and the attribute has a non-default value, do not change it.
 * If the attribute is not present or has a default value, and if there is metadata
 * for that attribute, merge the metadata attribute. This take place inline in the 
 * main loop of this method. If after the metadata merge the attribute 
 * still does not have a value, merge the template value. This takes place
 * in the AdhocWebService.applyTemplate() method.
 * If the template does not have a value, do nothing (the default will be used).
 * 
 * @param reportDoc
 * @param reportXML
 * @param templatePath
 * @param mqlNode
 * @param repository
 * @param userSession
 * @return
 * @throws IOException
 * @throws AdhocWebServiceException
 * @throws PentahoMetadataException
 */
public void createJFreeReportDefinitionAsStream(String reportXML, String templatePath, Element mqlNode,
        IPentahoSession userSession, OutputStream jfreeMergedOutputStream)
        throws IOException, AdhocWebServiceException, PentahoMetadataException {

    Map reportSpecTypeToElement = null;
    Document templateDoc = null;
    Element templateItems = null;
    boolean bUseTemplate = !StringUtils.isEmpty(templatePath);

    if (bUseTemplate) {
        templatePath = AdhocContentGenerator.WAQR_REPOSITORY_PATH + templatePath;
        try {
            org.dom4j.io.SAXReader reader = new org.dom4j.io.SAXReader();
            reader.setEntityResolver(new SolutionURIResolver());
            templateDoc = reader
                    .read(ActionSequenceResource.getInputStream(templatePath, LocaleHelper.getLocale()));
        } catch (Throwable t) {
            // XML document can't be read. We'll just return a null document.
        }

        templateItems = (Element) templateDoc.selectSingleNode("/report/items"); //$NON-NLS-1$
        List nodes = templateItems.elements();
        Iterator it = nodes.iterator();
        reportSpecTypeToElement = new HashMap();
        while (it.hasNext()) {
            Element element = (Element) it.next();
            reportSpecTypeToElement.put(element.getName(), element);
        }
    }

    // get the business model from the mql statement
    String xml = mqlNode.asXML();

    // first see if it's a thin model...
    QueryXmlHelper helper = new QueryXmlHelper();
    IMetadataDomainRepository repo = PentahoSystem.get(IMetadataDomainRepository.class, null);
    Query queryObject = null;
    try {
        queryObject = helper.fromXML(repo, xml);
    } catch (Exception e) {
        String msg = Messages.getInstance()
                .getErrorString("HttpWebService.ERROR_0001_ERROR_DURING_WEB_SERVICE"); //$NON-NLS-1$
        error(msg, e);
        throw new AdhocWebServiceException(msg, e);
    }

    LogicalModel model = null;
    if (queryObject != null) {
        model = queryObject.getLogicalModel();
    }
    if (model == null) {
        throw new AdhocWebServiceException(
                Messages.getInstance().getErrorString("AdhocWebService.ERROR_0003_BUSINESS_VIEW_INVALID")); //$NON-NLS-1$
    }

    String locale = LocaleHelper.getClosestLocale(LocaleHelper.getLocale().toString(),
            queryObject.getDomain().getLocaleCodes());

    String reportXMLEncoding = XmlHelper.getEncoding(reportXML);
    ByteArrayInputStream reportSpecInputStream = new ByteArrayInputStream(
            reportXML.getBytes(reportXMLEncoding));
    ReportSpec reportSpec = (ReportSpec) CastorUtility.getInstance().readCastorObject(reportSpecInputStream,
            ReportSpec.class, reportXMLEncoding);
    if (reportSpec == null) {
        throw new AdhocWebServiceException(
                Messages.getInstance().getErrorString("AdhocWebService.ERROR_0002_REPORT_INVALID")); //$NON-NLS-1$
    }

    // ========== begin column width stuff

    // make copies of the business columns; in the next step we're going to fill out any missing column widths
    LogicalColumn[] columns = new LogicalColumn[reportSpec.getField().length];
    for (int i = 0; i < reportSpec.getField().length; i++) {
        Field field = reportSpec.getField()[i];
        String name = field.getName();
        LogicalColumn column = model.findLogicalColumn(name);
        columns[i] = (LogicalColumn) column.clone();
    }

    boolean columnWidthUnitsConsistent = AdhocContentGenerator.areMetadataColumnUnitsConsistent(reportSpec,
            model);

    if (!columnWidthUnitsConsistent) {
        logger.error(Messages.getInstance()
                .getErrorString("AdhocWebService.ERROR_0013_INCONSISTENT_COLUMN_WIDTH_UNITS")); //$NON-NLS-1$
    } else {
        double columnWidthScaleFactor = 1.0;
        int missingColumnWidthCount = 0;
        int columnWidthSumOfPercents;
        double defaultWidth;
        columnWidthSumOfPercents = AdhocContentGenerator.getSumOfMetadataColumnWidths(reportSpec, model);
        missingColumnWidthCount = AdhocContentGenerator.getMissingColumnWidthCount(reportSpec, model);

        // if there are columns with no column width specified, figure out what percent we should use for them
        if (missingColumnWidthCount > 0) {
            if (columnWidthSumOfPercents < 100) {
                int remainingPercent = 100 - columnWidthSumOfPercents;
                defaultWidth = remainingPercent / missingColumnWidthCount;
                columnWidthSumOfPercents = 100;
            } else {
                defaultWidth = 10;
                columnWidthSumOfPercents += (missingColumnWidthCount * 10);
            }

            // fill in columns without column widths
            for (int i = 0; i < columns.length; i++) {
                ColumnWidth property = (ColumnWidth) columns[i]
                        .getProperty(DefaultPropertyID.COLUMN_WIDTH.getId());
                if (property == null) {
                    property = new ColumnWidth(WidthType.PERCENT, defaultWidth);
                    columns[i].setProperty(DefaultPropertyID.COLUMN_WIDTH.getId(), property);
                }
            }
        }

        if (columnWidthSumOfPercents > 100) {
            columnWidthScaleFactor = 100.0 / (double) columnWidthSumOfPercents;
        }

        // now scale down if necessary
        if (columnWidthScaleFactor < 1.0) {
            for (int i = 0; i < columns.length; i++) {
                ColumnWidth property = (ColumnWidth) columns[i]
                        .getProperty(DefaultPropertyID.COLUMN_WIDTH.getId());
                ColumnWidth newProperty = new ColumnWidth(property.getType(),
                        columnWidthScaleFactor * property.getWidth());
                columns[i].setProperty(DefaultPropertyID.COLUMN_WIDTH.getId(), newProperty);
            }
        }

    }

    // ========== end column width stuff

    for (int i = 0; i < reportSpec.getField().length; i++) {
        Field field = reportSpec.getField()[i];
        LogicalColumn column = columns[i];

        applyMetadata(field, column, columnWidthUnitsConsistent, locale);

        // Template properties have the lowest priority, merge them last
        if (bUseTemplate) {
            Element templateDefaults = null;
            if (column.getDataType() != null) {
                templateDefaults = (Element) reportSpecTypeToElement
                        .get(AdhocContentGenerator.METADATA_TYPE_TO_REPORT_SPEC_TYPE.get(column.getDataType())); // sorry, this is ugly as hell
            }
            /*
             * NOTE: this merge of the template with the node's properties only sets the following properties:
             * format, fontname, fontsize, color, alignment, vertical-alignment, 
             */
            AdhocContentGenerator.applyTemplate(field, templateDefaults);
        }
        AdhocContentGenerator.applyDefaults(field);
    } // end for

    /*
     * Create the xml document (generatedJFreeDoc) containing the jfreereport definition using
     * the reportSpec as input. generatedJFreeDoc will have the metadata merged with it,
     * and some of the template.
     */
    ByteArrayOutputStream jfreeOutputStream = new ByteArrayOutputStream();
    ReportGenerationUtility.createJFreeReportXMLAsStream(reportSpec, reportXMLEncoding,
            (OutputStream) jfreeOutputStream);
    String jfreeXml = jfreeOutputStream.toString(reportXMLEncoding);
    Document generatedJFreeDoc = null;
    try {
        generatedJFreeDoc = XmlDom4JHelper.getDocFromString(jfreeXml, new PentahoEntityResolver());
    } catch (XmlParseException e) {
        String msg = Messages.getInstance()
                .getErrorString("HttpWebService.ERROR_0001_ERROR_DURING_WEB_SERVICE"); //$NON-NLS-1$
        error(msg, e);
        throw new AdhocWebServiceException(msg, e);
    }

    /*
     * Merge template's /report/items element's attributes into the
     * generated document's /report/items element's attributes. There should not be any
     * conflict with the metadata, or the xreportspec in the reportXML param
     */
    if (bUseTemplate) {
        Element reportItems = (Element) generatedJFreeDoc.selectSingleNode("/report/items"); //$NON-NLS-1$
        List templateAttrs = templateItems.attributes(); // from the template's /report/items element
        Iterator templateAttrsIt = templateAttrs.iterator();

        while (templateAttrsIt.hasNext()) {
            Attribute attr = (Attribute) templateAttrsIt.next();
            String name = attr.getName();
            String value = attr.getText();

            Node node = reportItems.selectSingleNode("@" + name); //$NON-NLS-1$
            if (node != null) {
                node.setText(value);
            } else {
                reportItems.addAttribute(name, value);
            }
        }
        List templateElements = templateItems.elements();
        Iterator templateElementsIt = templateElements.iterator();
        while (templateElementsIt.hasNext()) {
            Element element = (Element) templateElementsIt.next();
            element.detach();
            reportItems.add(element);
        }
        /*
         * NOTE: this merging of the template (ReportGenerationUtility.mergeTemplate())
         * with the generated document can wait until last because none of the 
         * properties involved in this merge are settable by the metadata or the WAQR UI
         */
        ReportGenerationUtility.mergeTemplateAsStream(templateDoc, generatedJFreeDoc, jfreeMergedOutputStream);
    } else {
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding(reportXMLEncoding);
        XMLWriter writer = new XMLWriter(jfreeMergedOutputStream, format);
        writer.write(generatedJFreeDoc);
        writer.close();
    }
}