/** * Process index terms. * * @param theInput input document * @return read index terms * @throws ProcessException if processing index terms failed */ public IndexPreprocessResult process(final Document theInput) throws ProcessException { final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder = null; try { documentBuilder = documentBuilderFactory.newDocumentBuilder(); } catch (final ParserConfigurationException e) { throw new RuntimeException("Unable to create a document builder: " + e.getMessage(), e); } final Document doc = documentBuilder.newDocument(); final Node rootElement = theInput.getDocumentElement(); final ArrayList<IndexEntry> indexes = new ArrayList<IndexEntry>(); final IndexEntryFoundListener listener = new IndexEntryFoundListener() { public void foundEntry(final IndexEntry theEntry) { indexes.add(theEntry); } }; final Node node = processCurrNode(rootElement, doc, listener)[0]; doc.appendChild(node); doc.getDocumentElement().setAttribute(XMLNS_ATTRIBUTE + ":" + this.prefix, this.namespace_url); return new IndexPreprocessResult(doc, (IndexEntry[]) indexes.toArray(new IndexEntry[0])); }
public void createAndAddIndexGroups( final IndexEntry[] theIndexEntries, final IndexConfiguration theConfiguration, final Document theDocument, final Locale theLocale) { final IndexComparator indexEntryComparator = new IndexComparator(theLocale); final IndexGroup[] indexGroups = indexGroupProcessor.process(theIndexEntries, theConfiguration, theLocale); final Element rootElement = theDocument.getDocumentElement(); final Element indexGroupsElement = theDocument.createElementNS(namespace_url, "index.groups"); indexGroupsElement.setPrefix(prefix); for (final IndexGroup group : indexGroups) { // Create group element final Node groupElement = theDocument.createElementNS(namespace_url, "index.group"); groupElement.setPrefix(prefix); // Create group label element and index entry childs final Element groupLabelElement = theDocument.createElementNS(namespace_url, "label"); groupLabelElement.setPrefix(prefix); groupLabelElement.appendChild(theDocument.createTextNode(group.getLabel())); groupElement.appendChild(groupLabelElement); final Node[] entryNodes = transformToNodes(group.getEntries(), theDocument, indexEntryComparator); for (final Node entryNode : entryNodes) { groupElement.appendChild(entryNode); } indexGroupsElement.appendChild(groupElement); } rootElement.appendChild(indexGroupsElement); }
/** * Processes curr node. Copies node to the target document if its is not a text node of index * entry element. Otherwise it process it and creates nodes with "prefix" in given "namespace_url" * from the parsed index entry text. * * @param theNode node to process * @param theTargetDocument target document used to import and create nodes * @param theIndexEntryFoundListener listener to notify that new index entry was found * @return the array of nodes after processing input node */ private Node[] processCurrNode( final Node theNode, final Document theTargetDocument, final IndexEntryFoundListener theIndexEntryFoundListener) { final NodeList childNodes = theNode.getChildNodes(); if (checkElementName(theNode)) { return processIndexNode(theNode, theTargetDocument, theIndexEntryFoundListener); } else { final Node result = theTargetDocument.importNode(theNode, false); for (int i = 0; i < childNodes.getLength(); i++) { final Node[] processedNodes = processCurrNode(childNodes.item(i), theTargetDocument, theIndexEntryFoundListener); for (final Node node : processedNodes) { result.appendChild(node); } } return new Node[] {result}; } }
/** * Creates element with "prefix" in "namespace_url" with given name for the target document * * @param theTargetDocument target document * @param theName name * @return new element */ private Element createElement(final Document theTargetDocument, final String theName) { final Element indexEntryNode = theTargetDocument.createElementNS(this.namespace_url, theName); indexEntryNode.setPrefix(this.prefix); return indexEntryNode; }
/** * Creates nodes from index entries * * @param theIndexEntries index entries * @param theTargetDocument target document * @param theIndexEntryComparator comparator to sort the index entries. if it is null the index * entries will be unsorted * @return nodes for the target document */ private Node[] transformToNodes( final IndexEntry[] theIndexEntries, final Document theTargetDocument, final Comparator<IndexEntry> theIndexEntryComparator) { if (null != theIndexEntryComparator) { Arrays.sort(theIndexEntries, theIndexEntryComparator); } final List<Element> result = new ArrayList<Element>(); for (final IndexEntry indexEntry : theIndexEntries) { final Element indexEntryNode = createElement(theTargetDocument, "index.entry"); final Element formattedStringElement = createElement(theTargetDocument, "formatted-value"); if (indexEntry.getContents() != null) { for (final Iterator<Node> i = indexEntry.getContents().iterator(); i.hasNext(); ) { final Node child = i.next(); final Node clone = theTargetDocument.importNode(child, true); if (!i.hasNext() && clone.getNodeType() == Node.TEXT_NODE) { final Text t = (Text) clone; t.setData(t.getData().replaceAll("[\\s\\n]+$", "")); } formattedStringElement.appendChild(clone); } } else { final Text textNode = theTargetDocument.createTextNode(indexEntry.getFormattedString()); textNode.normalize(); formattedStringElement.appendChild(textNode); } indexEntryNode.appendChild(formattedStringElement); final String[] refIDs = indexEntry.getRefIDs(); for (final String refID : refIDs) { final Element referenceIDElement = createElement(theTargetDocument, "refID"); referenceIDElement.setAttribute("value", refID); indexEntryNode.appendChild(referenceIDElement); } final String val = indexEntry.getValue(); if (null != val) { indexEntryNode.setAttribute("value", val); } final String sort = indexEntry.getSortString(); if (null != sort) { indexEntryNode.setAttribute("sort-string", sort); } if (indexEntry.isStartingRange()) { indexEntryNode.setAttribute("start-range", "true"); } else if (indexEntry.isEndingRange()) { indexEntryNode.setAttribute("end-range", "true"); } if (indexEntry.isSuppressesThePageNumber()) { indexEntryNode.setAttribute("no-page", "true"); } else if (indexEntry.isRestoresPageNumber()) { indexEntryNode.setAttribute("single-page", "true"); } final IndexEntry[] childIndexEntries = indexEntry.getChildIndexEntries(); final Node[] nodes = transformToNodes(childIndexEntries, theTargetDocument, theIndexEntryComparator); for (final Node node : nodes) { indexEntryNode.appendChild(node); } final IndexEntry[] seeChildIndexEntries = indexEntry.getSeeChildIndexEntries(); if (seeChildIndexEntries != null) { final Element seeElement = createElement(theTargetDocument, "see-childs"); final Node[] seeNodes = transformToNodes(seeChildIndexEntries, theTargetDocument, theIndexEntryComparator); for (final Node node : seeNodes) { seeElement.appendChild(node); } indexEntryNode.appendChild(seeElement); } final IndexEntry[] seeAlsoChildIndexEntries = indexEntry.getSeeAlsoChildIndexEntries(); if (seeAlsoChildIndexEntries != null) { final Element seeAlsoElement = createElement(theTargetDocument, "see-also-childs"); final Node[] seeAlsoNodes = transformToNodes(seeAlsoChildIndexEntries, theTargetDocument, theIndexEntryComparator); for (final Node node : seeAlsoNodes) { seeAlsoElement.appendChild(node); } indexEntryNode.appendChild(seeAlsoElement); } result.add(indexEntryNode); } return (Node[]) result.toArray(new Node[result.size()]); }