Search in sources :

Example 1 with Consumer

use of com.vladsch.flexmark.util.Consumer in project flexmark-java by vsch.

the class XmlDocxSorter method sortDocumentParts.

public static String sortDocumentParts(String xml) {
    try {
        final InputSource src = new InputSource(new StringReader(xml));
        final DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
        builderFactory.setNamespaceAware(false);
        final Document document = builderFactory.newDocumentBuilder().parse(src);
        final DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
        final DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS");
        final LSSerializer writer = impl.createLSSerializer();
        // Set this to true if the output needs to be beautified.
        writer.getDomConfig().setParameter("format-pretty-print", Boolean.TRUE);
        writer.getDomConfig().setParameter("xml-declaration", false);
        final HashMap<String, HashMap<Pattern, DocxPartEntry>> contentTypeNameEntry = new HashMap<String, HashMap<Pattern, DocxPartEntry>>();
        for (DocxPartEntry entry : entries) {
            HashMap<Pattern, DocxPartEntry> entryHashMap = contentTypeNameEntry.get(entry.contentType);
            if (entryHashMap == null) {
                entryHashMap = new HashMap<>();
                contentTypeNameEntry.put(entry.contentType, entryHashMap);
            }
            entryHashMap.put(entry.regex, entry);
        }
        final DocxPartEntry unknownPartEntry = new DocxPartEntry(99, "", "");
        final ArrayList<DocxPartEntry> partEntries = new ArrayList<>();
        final int[] unknownIndex = new int[] { 0 };
        // final NodeList parts = document.getElementsByTagName("pkg:part");
        final StringBuilder sb = new StringBuilder();
        sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
        forAllChildren(document, XMLNS_PKG, arrayOf("package"), new Consumer<Node>() {

            @Override
            public void accept(final Node pkg) {
                forAllChildren(pkg, XMLNS_PKG, arrayOf("part"), new Consumer<Node>() {

                    @Override
                    public void accept(final Node part) {
                        sortNodeAttributes(part);
                        sortRelationships(part);
                        sortProperties(part);
                        final NamedNodeMap attributes = part.getAttributes();
                        final Node contentTypeNode = attributes.getNamedItem("pkg:contentType");
                        boolean handled = false;
                        if (contentTypeNode != null) {
                            String contentType = contentTypeNode.getNodeValue();
                            final HashMap<Pattern, DocxPartEntry> entryHashMap = contentTypeNameEntry.get(contentType);
                            if (entryHashMap != null) {
                                final Node nameNode = attributes.getNamedItem("pkg:name");
                                // now we find the entry for these
                                if (nameNode != null) {
                                    String name = nameNode.getNodeValue();
                                    for (Entry<Pattern, DocxPartEntry> entry : entryHashMap.entrySet()) {
                                        Matcher matcher = entry.getKey().matcher(name);
                                        if (matcher.matches()) {
                                            int index = matcher.groupCount() > 0 ? Integer.parseInt(matcher.group(1)) : 0;
                                            partEntries.add(new DocxPartEntry(entry.getValue(), part, index));
                                            handled = true;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                        if (!handled) {
                            // make it unknown
                            partEntries.add(new DocxPartEntry(unknownPartEntry, part, ++unknownIndex[0]));
                        }
                    }
                });
                for (DocxPartEntry pe : partEntries) {
                    pkg.removeChild(pe.node);
                }
                Collections.sort(partEntries, new Comparator<DocxPartEntry>() {

                    @Override
                    public int compare(final DocxPartEntry o1, final DocxPartEntry o2) {
                        final int ordinals = Integer.compare(o1.ordinal, o2.ordinal);
                        return ordinals != 0 ? ordinals : Integer.compare(o1.index, o2.index);
                    }
                });
                for (DocxPartEntry pe : partEntries) {
                    pkg.appendChild(pe.node);
                }
                sb.append(writer.writeToString(pkg));
            }
        });
        return sb.toString();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
Also used : InputSource(org.xml.sax.InputSource) DocumentBuilderFactory(javax.xml.parsers.DocumentBuilderFactory) Matcher(java.util.regex.Matcher) DOMImplementationLS(org.w3c.dom.ls.DOMImplementationLS) Node(org.w3c.dom.Node) Document(org.w3c.dom.Document) Consumer(com.vladsch.flexmark.util.Consumer) StringReader(java.io.StringReader) DOMImplementationRegistry(org.w3c.dom.bootstrap.DOMImplementationRegistry) Pattern(java.util.regex.Pattern) NamedNodeMap(org.w3c.dom.NamedNodeMap) LSSerializer(org.w3c.dom.ls.LSSerializer)

Aggregations

Consumer (com.vladsch.flexmark.util.Consumer)1 StringReader (java.io.StringReader)1 Matcher (java.util.regex.Matcher)1 Pattern (java.util.regex.Pattern)1 DocumentBuilderFactory (javax.xml.parsers.DocumentBuilderFactory)1 Document (org.w3c.dom.Document)1 NamedNodeMap (org.w3c.dom.NamedNodeMap)1 Node (org.w3c.dom.Node)1 DOMImplementationRegistry (org.w3c.dom.bootstrap.DOMImplementationRegistry)1 DOMImplementationLS (org.w3c.dom.ls.DOMImplementationLS)1 LSSerializer (org.w3c.dom.ls.LSSerializer)1 InputSource (org.xml.sax.InputSource)1