Example usage for org.dom4j Element addComment

List of usage examples for org.dom4j Element addComment

Introduction

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

Prototype

Element addComment(String comment);

Source Link

Document

Adds a new Comment node with the given text to this element.

Usage

From source file:org.jbpm.jpdl.internal.convert.Jpdl3Converter.java

License:Open Source License

/**
 * Call this method to convert the jpdl3 process.
 * The return value will be a converted jpdl4 XML model.
 *///w w  w. j a  v  a2  s .co  m
public Document readAndConvert() {

    // create a new definition
    jpdl4Document = DocumentHelper.createDocument();

    // initialize lists
    problems = new ArrayList<Problem>();
    unresolvedTransitionDestinations = new ArrayList<Object[]>();
    unresolvedActionReferences = new ArrayList<Object[]>();

    try {

        // parse the document into a XML dom tree
        jpdl3Document = Jpdl3ConverterParser.parse(inputSource, this);
        jpdl4Document.setXMLEncoding(jpdl3Document.getXMLEncoding());

        // Convert the root element 
        Element jpdl3Root = jpdl3Document.getRootElement();
        Element jpdl4Root = parseProcessDefinitionAttributes(jpdl3Root);

        // convert process description as comment
        String description = jpdl3Root.elementTextTrim("description");
        if (description != null) {
            jpdl4Root.addComment(description);
        }

        // first pass
        convertSwimlanes(jpdl3Root, jpdl4Root);
        convertActions(jpdl3Root, null, null); // Todo: refactor
        convertNodes(jpdl3Root, jpdl4Root);
        convertEvents(jpdl3Root, jpdl4Root);
        convertExceptionHandlers(jpdl3Root, jpdl4Root);
        convertTasks(jpdl3Root, jpdl4Root);

        // second pass processing: process any unresolved elements 
        resolveTransitionDestinations();
        //resolveActionReferences(); // not yet implemented
        verifySwimlaneAssignments();

    } catch (Exception e) {
        log.error("couldn't parse process definition", e);
        addProblem(new Problem(Problem.LEVEL_ERROR, "couldn't parse process definition", e));
    }

    // After conversion: check if there were any conversion problems

    if (Problem.containsProblemsOfLevel(problems, Problem.LEVEL_ERROR)) {
        throw new ConvertException(problems);
    }

    if (problems != null) {
        for (Problem problem : problems) {
            log.warn("process parse warning: " + problem.getDescription());
        }
    }

    return jpdl4Document;
}

From source file:org.jbpm.jpdl.internal.convert.Jpdl3Converter.java

License:Open Source License

public Element convertTask(Element taskElement, Element jpdlElement) {

    Element task4 = jpdlElement.addElement("task");
    String name = taskElement.attributeValue("name");
    if (name != null) {
        task4.attributeValue("name", name);
    }//from   w  ww. ja  v  a2 s . com

    String description = taskElement.elementTextTrim("description");
    if (description != null) {
        task4.addComment(description);
    }

    String condition = taskElement.elementTextTrim("condition");
    if (condition == null) {
        condition = taskElement.attributeValue("condition");
    }
    if (condition == null) {
        addWarning("Unsupported condition attribute converstion for task : " + taskElement.asXML());
    }

    //The converted the elements in task should be in this sequence 
    //assignment-handler, on, notification, reminder, timer

    // assignment
    String swimlaneName = taskElement.attributeValue("swimlane");
    Element assignmentElement = taskElement.element("assignment");

    // if there is a swimlane attribute specified
    if (swimlaneName != null) {

        Element swimLane = swimlanesCollection.get(swimlaneName);
        if (swimLane == null) {
            addWarning("task references unknown swimlane '" + swimlaneName + "':" + taskElement.asXML());
        } else {
            task4.addAttribute("swimlane", swimlaneName);
        }
    } else if (assignmentElement != null) {
        if ((assignmentElement.attribute("actor-id") != null)
                || (assignmentElement.attribute("pooled-actors") != null)) {

            String actorid = assignmentElement.attributeValue("actor-id");
            String pooledactors = assignmentElement.attributeValue("pooled-actors");

            if (actorid != null) {
                task4.addAttribute("assignee", actorid);
            }
            if (pooledactors != null) {
                task4.addAttribute("candidate-groups", pooledactors);
            }

        } else {
            convertAssignmentDelegation(assignmentElement, task4);
        }
    } else {
        // the user has to manage assignment manually, so we better inform him/her.
        log.info("process xml information: no swimlane or assignment specified for task '" + taskElement.asXML()
                + "'");
    }

    //notification attribute
    String notificationsText = taskElement.attributeValue("notify");
    if (notificationsText != null && ("true".equalsIgnoreCase(notificationsText)
            || "on".equalsIgnoreCase(notificationsText) || "yes".equalsIgnoreCase(notificationsText))) {
        //TODO:Review if there is "continue" attribute to converted
        Element notify = task4.addElement("notification");
        notify.addAttribute("continue", "sync");
    }
    //Reminder elements
    convertTaskReminders(taskElement, task4);

    //event elements  
    convertEvents(taskElement, task4);

    //timer elements
    convertTaskTimers(taskElement, task4);

    convertExceptionHandlers(taskElement, task4);

    String duedateText = taskElement.attributeValue("duedate");

    if (duedateText != null) {
        addWarning("Unsupported duedateDate attribute converstion for task : " + taskElement.asXML());
    }

    String priorityText = taskElement.attributeValue("priority");
    if (priorityText != null) {
        addWarning("Unsupported priorityText attribute converstion for task : " + taskElement.asXML());
    }

    String blockingText = taskElement.attributeValue("blocking");
    if (blockingText != null) {
        addWarning("Unsupported blocking attribute converstion for task : " + taskElement.asXML());
    }

    String signallingText = taskElement.attributeValue("signalling");
    if (signallingText != null) {
        addWarning("Unsupported signallingText attribute converstion for task : " + taskElement.asXML());
    }

    Element taskControllerElement = taskElement.element("controller");
    if (taskControllerElement != null) {
        addWarning("Unsupported controller converstion for task : " + taskElement.asXML());
    }

    return task4;
}

From source file:org.jbpm.jpdl.internal.convert.Jpdl3Converter.java

License:Open Source License

protected void convertAssignmentDelegation(Element jpdl3AssignmentElement, Element jpdl4Task) {

    String expression = jpdl3AssignmentElement.attributeValue("expression");
    String actorId = jpdl3AssignmentElement.attributeValue("actor-id");
    String pooledActors = jpdl3AssignmentElement.attributeValue("pooled-actors");

    if (expression != null) {

        // TODO:How to convert default assignmenthandler?
        // assignmentDelegation.setClassName("org.jbpm.identity.assignment.ExpressionAssignmentHandler");
        // assignmentDelegation.setConfiguration("<expression>" + expression +
        // "</expression>");

    } else if ((actorId != null) || (pooledActors != null)) {

        jpdl4Task.addComment(
                "Please Update the AssignmentHandler and implement org.jbpm.api.task.AssignmentHandler to create your own AssignmentHandler.");
        Element assignmentHandler = jpdl4Task.addElement("assignment-handler");
        assignmentHandler.addAttribute("class", "org.jbpm.taskmgmt.assignment.ActorAssignmentHandler");

        String configuration = "";
        if (actorId != null) {
            configuration += "<actorId>" + actorId + "</actorId>";
        }//from  w w w.j a v a 2s .  c o m
        if (pooledActors != null) {
            configuration += "<pooledActors>" + pooledActors + "</pooledActors>";
        }

    } else {
        String claz = jpdl3AssignmentElement.attributeValue("class");
        Element assignmentHandler = jpdl4Task.addElement("assignment-handler");
        assignmentHandler.addAttribute("class", claz);
    }
}

From source file:org.jbpm.jpdl.internal.convert.Jpdl3Converter.java

License:Open Source License

public void convertNode(Element jpdl3Element, Element jpdl4Element) {

    String name = jpdl3Element.attributeValue("name");
    if (name != null) {
        jpdl4Element.addAttribute("name", name);
        nodeCollection.put(name, jpdl4Element);
    }// ww w . java  2  s . c  om

    // get the node description
    String description = jpdl3Element.elementTextTrim("description");
    if (description != null) {
        jpdl4Element.addComment(description);
    }

    String asyncText = jpdl3Element.attributeValue("async");
    if ("true".equalsIgnoreCase(asyncText)) {
        jpdl4Element.addAttribute("continue", "async");
    } else if ("exclusive".equalsIgnoreCase(asyncText)) {
        jpdl4Element.addAttribute("continue", "exclusive");
    } //else if -> uses the default continue="sync"

    // parse common subelements

    convertNodeTimers(jpdl3Element, jpdl4Element);
    convertEvents(jpdl3Element, jpdl4Element);
    convertExceptionHandlers(jpdl3Element, jpdl4Element);

    // save the transitions and parse them at the end
    addUnresolvedTransitionDestination(jpdl3Element, jpdl4Element);
}

From source file:org.jbpm.jpdl.internal.convert.Jpdl3Converter.java

License:Open Source License

public void resolveTransitionDestination(Element transitionElement, Element jpdl4Element) {

    Element transition4 = jpdl4Element.addElement("transition");
    transition4.addAttribute("name", transitionElement.attributeValue("name"));
    if (transitionElement.elementTextTrim("description") != null) {
        transition4.addComment(transitionElement.elementTextTrim("description"));
    }/*  ww w.ja  v a2s .  c  om*/
    //Get condition from jpdl3 element
    String condition = transitionElement.attributeValue("condition");
    if (condition == null) {
        Element conditionElement = transitionElement.element("condition");
        if (conditionElement != null) {
            condition = conditionElement.getTextTrim();
            // for backwards compatibility
            if ((condition == null) || (condition.length() == 0)) {
                condition = conditionElement.attributeValue("expression");
            }
        }
    }

    if (condition != null && condition.length() > 0) {
        Element condition4 = transition4.addElement("condition");
        condition4.addAttribute("expr", condition);
    }

    // set destinationNode of the transition
    String toName = transitionElement.attributeValue("to");
    if (toName == null) {
        addWarning("node '" + transitionElement.getPath()
                + "' has a transition without a 'to'-attribute to specify its destinationNode");
    } else {
        Element to = this.findNode(toName);
        if (to == null) {
            addWarning("transition to='" + toName + "' on node '" + transitionElement.getName()
                    + "' cannot be resolved");
        }

        transition4.addAttribute("to", toName);
    }

    // read the actions
    convertActions(transitionElement, transition4, "");

    convertExceptionHandlers(transitionElement, transition4);
}

From source file:org.jbpm.jpdl.xml.JpdlXmlWriter.java

License:Open Source License

private void writeComment(Element element, String comment) {
    element.addText(System.getProperty("line.separator"));
    element.addComment(" " + comment + " ");
}

From source file:org.jenkins.tools.test.model.MavenPom.java

License:Open Source License

public void addDependencies(Map<String, VersionNumber> toAdd, Map<String, VersionNumber> toReplace,
        VersionNumber coreDep, Map<String, String> pluginGroupIds) throws IOException {
    File pom = new File(rootDir.getAbsolutePath() + "/" + pomFileName);
    Document doc;//from   w  w w . j  a v  a  2s.  com
    try {
        doc = new SAXReader().read(pom);
    } catch (DocumentException x) {
        throw new IOException(x);
    }
    Element dependencies = doc.getRootElement().element("dependencies");
    if (dependencies == null) {
        dependencies = doc.getRootElement().addElement("dependencies");
    }
    for (Element mavenDependency : (List<Element>) dependencies.elements("dependency")) {
        Element artifactId = mavenDependency.element("artifactId");
        if (artifactId == null || !"maven-plugin".equals(artifactId.getTextTrim())) {
            continue;
        }
        Element version = mavenDependency.element("version");
        if (version == null || version.getTextTrim().startsWith("${")) {
            // Prior to 1.532, plugins sometimes assumed they could pick up the Maven plugin version from their parent POM.
            if (version != null) {
                mavenDependency.remove(version);
            }
            version = mavenDependency.addElement("version");
            version.addText(coreDep.toString());
        }
    }
    for (Element mavenDependency : (List<Element>) dependencies.elements("dependency")) {
        Element artifactId = mavenDependency.element("artifactId");
        if (artifactId == null) {
            continue;
        }
        excludeSecurity144Compat(mavenDependency);
        VersionNumber replacement = toReplace.get(artifactId.getTextTrim());
        if (replacement == null) {
            continue;
        }
        Element version = mavenDependency.element("version");
        if (version != null) {
            mavenDependency.remove(version);
        }
        version = mavenDependency.addElement("version");
        version.addText(replacement.toString());
    }
    dependencies.addComment("SYNTHETIC");
    for (Map.Entry<String, VersionNumber> dep : toAdd.entrySet()) {
        Element dependency = dependencies.addElement("dependency");
        String group = pluginGroupIds.get(dep.getKey());

        // Handle cases where plugin isn't under default groupId
        if (group != null && !group.isEmpty()) {
            dependency.addElement("groupId").addText(group);
        } else {
            dependency.addElement("groupId").addText("org.jenkins-ci.plugins");
        }
        dependency.addElement("artifactId").addText(dep.getKey());
        dependency.addElement("version").addText(dep.getValue().toString());
        excludeSecurity144Compat(dependency);
    }
    FileWriter w = new FileWriter(pom);
    try {
        doc.write(w);
    } finally {
        w.close();
    }
}

From source file:org.mitre.ace2004.callisto.ExportAPF5_0_2.java

License:Open Source License

/**
 * Open and convert the data at the specified URI, to a new
 * AWBDocument. Implementations should verify that the URI specified is
 * absolute. URI's are used due to ambiguities in the URL class.
 *
 * @see URI#isAbsolute//www. j  a va2 s . c  om
 * @param doc the data to be exported
 * @param uri location to save data to
 * @return true if the export succeded, false otherwise.
 * @throws IOException on error writing to file.
 * @throws IllegalArgumentException implementations should throw an
 *         IllegalArgumentException if the uri specified is of an unsupported
 *         scheme, or if the preconditions of that scheme are not met (file:
 *         and http: protocols require the uri be absolute and heirarchal).
 */
public boolean exportDocument(AWBDocument awbDoc, URI uri) throws IOException {

    // note that this only happens automatically on export of APF
    coreferenceRelations(awbDoc);

    Document xmlDoc = null;

    try {
        xmlDoc = DocumentHelper.createDocument();
        xmlDoc.addDocType("source_file", "SYSTEM", "apf.v" + APF_VERSION + ".dtd");

        String encoding = awbDoc.getEncoding();

        // if this document came from import, it will have 'source' (maybe)
        // and 'uri' specified by the 'source_file' tag. keep them.
        String source = (String) awbDoc.getClientProperty(IdTracker.DOC_SOURCE);
        if (source == null)
            source = "unknown";

        URI signalURI = (URI) awbDoc.getClientProperty(IdTracker.DOC_URI);
        if (signalURI == null)
            signalURI = awbDoc.getSignalURI();

        // relativize with destination URI
        String path = uri.getRawPath();
        URI base = uri.resolve(path.substring(0, path.lastIndexOf('/') + 1));
        signalURI = base.relativize(signalURI);

        // what's the point in versioning by X.0 if every X.y is incompatable?
        Element root = xmlDoc.addElement("source_file").addAttribute("TYPE", "text")
                .addAttribute("VERSION", "5.0").addAttribute("SOURCE", source)
                .addAttribute("URI", signalURI.toString()).addAttribute("ENCODING", encoding);

        // warning to users reading the xml
        if (!encoding.equals("UTF-8"))
            root.addComment(
                    "This document is encoded in 'UTF-8'," + " the /source/ is encoded in '" + encoding + "'");

        Element doc = root.addElement("document").addAttribute("DOCID", IdTracker.getDocId(awbDoc));

        // don't know the order returned, so make collections
        HashSet entities = new LinkedHashSet();
        HashSet relations = new LinkedHashSet();
        HashSet events = new LinkedHashSet();
        HashSet quantities = new LinkedHashSet();

        Iterator annotIter = awbDoc.getAllAnnotations();
        while (annotIter.hasNext()) {
            AWBAnnotation annot = (AWBAnnotation) annotIter.next();
            String type = annot.getAnnotationType().getName();

            if (type.equals(ACE2004Task.ENTITY_TYPE_NAME))
                entities.add(annot);

            else if (type.equals(ACE2004Task.QUANTITY_TYPE_NAME))
                quantities.add(annot);

            else if (type.equals(ACE2004Task.RELATION_TYPE_NAME))
                relations.add(annot);

            else if (type.equals(ACE2004Task.EVENT_TYPE_NAME))
                events.add(annot);
        }

        if (DEBUG > 0) {
            System.err.println("Entities:   " + entities.size());
            System.err.println("Quantities: " + quantities.size());
            System.err.println("Relations:  " + relations.size());
            System.err.println("Events:     " + events.size());
        }
        // iterate over each
        Iterator iterator = null;

        iterator = entities.iterator();
        while (iterator.hasNext())
            addEntity(doc, awbDoc, (HasSubordinates) iterator.next());

        iterator = quantities.iterator();
        while (iterator.hasNext())
            addQuantity(doc, awbDoc, (HasSubordinates) iterator.next());

        iterator = relations.iterator();
        while (iterator.hasNext())
            addRelation(doc, awbDoc, (HasSubordinates) iterator.next());

        iterator = events.iterator();
        while (iterator.hasNext())
            addEvent(doc, awbDoc, (HasSubordinates) iterator.next());

    } catch (Exception t) {
        t.printStackTrace();
    }

    boolean success = writeAPF(xmlDoc, uri);
    if (DEBUG > 0) {
        System.err.println("\nExport succeeded: " + success + "\n");
    }
    return success;
}

From source file:org.mitre.ace2004.callisto.ExportAPF5_1_0.java

License:Open Source License

/**
 * Open and convert the data at the specified URI, to a new
 * AWBDocument. Implementations should verify that the URI specified is
 * absolute. URI's are used due to ambiguities in the URL class.
 *
 * @see URI#isAbsolute//  w ww.ja  v  a  2s . c  o m
 * @param doc the data to be exported
 * @param uri location to save data to
 * @return true if the export succeded, false otherwise.
 * @throws IOException on error writing to file.
 * @throws IllegalArgumentException implementations should throw an
 *         IllegalArgumentException if the uri specified is of an unsupported
 *         scheme, or if the preconditions of that scheme are not met (file:
 *         and http: protocols require the uri be absolute and heirarchal).
 */
public boolean exportDocument(AWBDocument awbDoc, URI uri) throws IOException {

    // note that this only happens automatically on export of APF
    coreferenceRelations(awbDoc);

    Document xmlDoc = null;

    try {
        xmlDoc = DocumentHelper.createDocument();
        xmlDoc.addDocType("source_file", "SYSTEM", "apf.v" + APF_VERSION + ".dtd");

        String encoding = awbDoc.getEncoding();

        // if this document came from import, it will have 'source' (maybe)
        // and 'uri' specified by the 'source_file' tag. keep them.
        String source = (String) awbDoc.getClientProperty(IdTracker.DOC_SOURCE);
        if (source == null)
            source = "unknown";

        URI signalURI = (URI) awbDoc.getClientProperty(IdTracker.DOC_URI);
        if (signalURI == null)
            signalURI = awbDoc.getSignalURI();

        // relativize with destination URI
        String path = uri.getRawPath();
        URI base = uri.resolve(path.substring(0, path.lastIndexOf('/') + 1));
        signalURI = base.relativize(signalURI);

        // Let's find out who the "author" of *this* version of the APF file is:
        String userSystemName = System.getProperty("user.name");

        // what's the point in versioning by X.0 if every X.y is incompatable?
        Element root = xmlDoc.addElement("source_file").addAttribute("URI", signalURI.toString())
                .addAttribute("SOURCE", source).addAttribute("TYPE", "text").addAttribute("VERSION", "5.0")
                .addAttribute("AUTHOR", userSystemName).addAttribute("ENCODING", encoding);

        // warning to users reading the xml
        if (!encoding.equals("UTF-8"))
            root.addComment(
                    "This document is encoded in 'UTF-8'," + " the /source/ is encoded in '" + encoding + "'");

        Element doc = root.addElement("document").addAttribute("DOCID", IdTracker.getDocId(awbDoc));

        // don't know the order returned, so make collections
        HashSet entities = new LinkedHashSet();
        HashSet relations = new LinkedHashSet();
        HashSet events = new LinkedHashSet();
        HashSet quantities = new LinkedHashSet();
        HashSet timex2entities = new LinkedHashSet();

        Iterator annotIter = awbDoc.getAllAnnotations();
        while (annotIter.hasNext()) {
            AWBAnnotation annot = (AWBAnnotation) annotIter.next();
            String type = annot.getAnnotationType().getName();

            if (type.equals(ACE2004Task.ENTITY_TYPE_NAME))
                entities.add(annot);

            else if (type.equals(ACE2004Task.QUANTITY_TYPE_NAME))
                quantities.add(annot);

            else if (type.equals(ACE2004Task.TIMEX2_TYPE_NAME))
                timex2entities.add(annot);

            else if (type.equals(ACE2004Task.RELATION_TYPE_NAME))
                relations.add(annot);

            else if (type.equals(ACE2004Task.EVENT_TYPE_NAME))
                events.add(annot);
        }

        if (DEBUG > 0) {
            System.err.println("Entities:       " + entities.size());
            System.err.println("Values:         " + quantities.size());
            System.err.println("Timex2Entities: " + timex2entities.size());
            System.err.println("Relations:      " + relations.size());
            System.err.println("Events:         " + events.size());
        }
        // iterate over each
        Iterator iterator = null;

        iterator = entities.iterator();
        while (iterator.hasNext())
            addEntity(doc, awbDoc, (HasSubordinates) iterator.next());

        iterator = quantities.iterator();
        while (iterator.hasNext())
            addQuantity(doc, awbDoc, (HasSubordinates) iterator.next());

        iterator = timex2entities.iterator();
        while (iterator.hasNext())
            addTimex2(doc, awbDoc, (TextExtentRegion) iterator.next());

        iterator = relations.iterator();
        while (iterator.hasNext())
            addRelation(doc, awbDoc, (HasSubordinates) iterator.next());

        iterator = events.iterator();
        while (iterator.hasNext())
            addEvent(doc, awbDoc, (HasSubordinates) iterator.next());

    } catch (Exception t) {
        t.printStackTrace();
    }

    boolean success = writeAPF(xmlDoc, uri);
    if (DEBUG > 0) {
        System.err.println("\nExport succeeded: " + success + "\n");
    }
    return success;
}

From source file:org.mitre.ace2004.callisto.ExportAPF5_1_1.java

License:Open Source License

/**
 * Open and convert the data at the specified URI, to a new
 * AWBDocument. Implementations should verify that the URI specified is
 * absolute. URI's are used due to ambiguities in the URL class.
 *
 * @see URI#isAbsolute//from w w w  .j  a va  2  s  . c om
 * @param doc the data to be exported
 * @param uri location to save data to
 * @return true if the export succeded, false otherwise.
 * @throws IOException on error writing to file.
 * @throws IllegalArgumentException implementations should throw an
 *         IllegalArgumentException if the uri specified is of an unsupported
 *         scheme, or if the preconditions of that scheme are not met (file:
 *         and http: protocols require the uri be absolute and heirarchal).
 */
public boolean exportDocument(AWBDocument awbDoc, URI uri) throws IOException {

    // note that this only happens automatically on export of APF
    coreferenceRelations(awbDoc);

    Document xmlDoc = null;

    try {
        xmlDoc = DocumentHelper.createDocument();
        xmlDoc.addDocType("source_file", "SYSTEM", "apf.v" + APF_VERSION + ".dtd");

        String encoding = awbDoc.getEncoding();

        // if this document came from import, it will have 'source' (maybe)
        // and 'uri' specified by the 'source_file' tag. keep them.
        String source = (String) awbDoc.getClientProperty(IdTracker.DOC_SOURCE);
        if (source == null)
            source = "unknown";

        URI signalURI = (URI) awbDoc.getClientProperty(IdTracker.DOC_URI);
        if (signalURI == null)
            signalURI = awbDoc.getSignalURI();

        // relativize with destination URI
        String path = uri.getRawPath();
        URI base = uri.resolve(path.substring(0, path.lastIndexOf('/') + 1));
        signalURI = base.relativize(signalURI);

        // Let's find out who the "author" of *this* version of the APF file is:
        String userSystemName = System.getProperty("user.name");

        // what's the point in versioning by X.0 if every X.y is incompatable?
        Element root = xmlDoc.addElement("source_file").addAttribute("URI", signalURI.toString())
                .addAttribute("SOURCE", source).addAttribute("TYPE", "text").addAttribute("VERSION", "5.0")
                .addAttribute("AUTHOR", userSystemName).addAttribute("ENCODING", encoding);

        // warning to users reading the xml
        if (!encoding.equals("UTF-8"))
            root.addComment(
                    "This document is encoded in 'UTF-8'," + " the /source/ is encoded in '" + encoding + "'");

        Element doc = root.addElement("document").addAttribute("DOCID", IdTracker.getDocId(awbDoc));

        // don't know the order returned, so make collections
        HashSet entities = new LinkedHashSet();
        HashSet relations = new LinkedHashSet();
        HashSet events = new LinkedHashSet();
        HashSet quantities = new LinkedHashSet();
        HashSet timex2entities = new LinkedHashSet();

        Iterator annotIter = awbDoc.getAllAnnotations();
        while (annotIter.hasNext()) {
            AWBAnnotation annot = (AWBAnnotation) annotIter.next();
            String type = annot.getAnnotationType().getName();

            if (type.equals(ACE2004Task.ENTITY_TYPE_NAME))
                entities.add(annot);

            else if (type.equals(ACE2004Task.QUANTITY_TYPE_NAME))
                quantities.add(annot);

            else if (type.equals(ACE2004Task.TIMEX2_TYPE_NAME))
                timex2entities.add(annot);

            else if (type.equals(ACE2004Task.RELATION_TYPE_NAME))
                relations.add(annot);

            else if (type.equals(ACE2004Task.EVENT_TYPE_NAME))
                events.add(annot);
        }

        if (DEBUG > 0) {
            System.err.println("Entities:       " + entities.size());
            System.err.println("Values:         " + quantities.size());
            System.err.println("Timex2Entities: " + timex2entities.size());
            System.err.println("Relations:      " + relations.size());
            System.err.println("Events:         " + events.size());
        }
        // iterate over each
        Iterator iterator = null;

        iterator = entities.iterator();
        while (iterator.hasNext())
            addEntity(doc, awbDoc, (HasSubordinates) iterator.next());

        iterator = quantities.iterator();
        while (iterator.hasNext())
            addQuantity(doc, awbDoc, (HasSubordinates) iterator.next());

        iterator = timex2entities.iterator();
        while (iterator.hasNext())
            addTimex2(doc, awbDoc, (TextExtentRegion) iterator.next());

        iterator = relations.iterator();
        while (iterator.hasNext())
            addRelation(doc, awbDoc, (HasSubordinates) iterator.next());

        iterator = events.iterator();
        while (iterator.hasNext())
            addEvent(doc, awbDoc, (HasSubordinates) iterator.next());

        addExternalResourceDeclarations(doc, awbDoc);

    } catch (Exception t) {
        t.printStackTrace();
    }

    boolean success = writeAPF(xmlDoc, uri);
    if (DEBUG > 0) {
        System.err.println("\nExport succeeded: " + success + "\n");
    }
    return success;
}