@Override public void endElement(final String uri, final String localName, final String name) throws SAXException { if (start) { level--; try { pushcontentWriter.writeEndElement(); } catch (XMLStreamException e) { throw new SAXException(e); } } if (level == 0) { // turn off start if we reach the end tag of staring element start = false; if (ATTR_CONACTION_VALUE_PUSHAFTER.equals(pushType) || ATTR_CONACTION_VALUE_PUSHREPLACE.equals(pushType)) { // if it is pushafter or replace, we need to record content in pushtable // if target == null we have already reported error in startElement; if (target != null) { if (pushcontentWriter != null) { try { pushcontentWriter.close(); } catch (final XMLStreamException e) { throw new SAXException(e); } } addtoPushTable(target, pushcontentDocumentFragment, pushType); pushcontentWriter = getXMLStreamWriter(); target = null; pushType = null; } } } }
/** * Write start element. * * @param elemName element name * @param atts attribute * @param removeConref whether remeove conref info * @throws SAXException if writing element failed */ private void putElement(final String elemName, final Attributes atts, final boolean removeConref) throws SAXException { // parameter boolean removeConref specifies whether to remove // conref information like @conref @conaction in current element // when copying it to pushcontent. True means remove and false means // not remove. try { pushcontentWriter.writeStartElement(elemName); for (int index = 0; index < atts.getLength(); index++) { final String name = atts.getQName(index); if (!removeConref || !ATTRIBUTE_NAME_CONREF.equals(name) && !ATTRIBUTE_NAME_CONACTION.equals(name)) { String value = atts.getValue(index); if (ATTRIBUTE_NAME_HREF.equals(name) || ATTRIBUTE_NAME_CONREF.equals(name)) { // adjust href for pushbefore and replace value = replaceURL(value); } final int offset = atts.getQName(index).indexOf(":"); final String prefix = offset != -1 ? atts.getQName(index).substring(0, offset) : ""; pushcontentWriter.writeAttribute( prefix, atts.getURI(index), atts.getLocalName(index), value); } } // id attribute should only be added to the starting element // which dosen't have id attribute set if (ATTR_CONACTION_VALUE_PUSHREPLACE.equals(pushType) && atts.getValue(ATTRIBUTE_NAME_ID) == null && level == 1) { final String fragment = target.getFragment(); if (fragment == null) { // if there is no '#' in target string, report error logger.error( MessageUtils.getInstance().getMessage("DOTJ041E", target.toString()).toString()); } else { String id = ""; // has element id if (fragment.contains(SLASH)) { id = fragment.substring(fragment.lastIndexOf(SLASH) + 1); } else { id = fragment; } // add id attribute pushcontentWriter.writeAttribute(ATTRIBUTE_NAME_ID, id); } } } catch (final XMLStreamException e) { throw new SAXException(e); } }
/** * @param target target * @param pushcontent content * @param type push type */ private void addtoPushTable(URI target, final DocumentFragment pushcontent, final String type) { if (target.getFragment() == null) { // if there is no '#' in target string, report error logger.error(MessageUtils.getInstance().getMessage("DOTJ041E", target.toString()).toString()); return; } if (target.getPath().isEmpty()) { // means conref the file itself target = toURI(parsefilename.getPath() + target); } final File key = toFile(FileUtils.resolve(fileDir, target)); Hashtable<MoveKey, DocumentFragment> table = null; if (pushtable.containsKey(key)) { // if there is something else push to the same file table = pushtable.get(key); } else { // if there is nothing else push to the same file table = new Hashtable<>(); pushtable.put(key, table); } final MoveKey moveKey = new MoveKey(SHARP + target.getFragment(), type); if (table.containsKey(moveKey)) { // if there is something else push to the same target // append content if type is 'pushbefore' or 'pushafter' // report error if type is 'replace' if (ATTR_CONACTION_VALUE_PUSHREPLACE.equals(type)) { logger.error( MessageUtils.getInstance().getMessage("DOTJ042E", target.toString()).toString()); } else { table.put(moveKey, appendPushContent(pushcontent, table.get(moveKey))); } } else { // if there is nothing else push to the same target table.put(moveKey, appendPushContent(pushcontent, null)); } }
@Override public void startElement( final String uri, final String localName, final String name, final Attributes atts) throws SAXException { if (start) { // if start is true, we need to record content in pushcontent // also we need to add level to make sure start is turn off // at the corresponding end element level++; putElement(name, atts, false); } final String conactValue = atts.getValue(ATTRIBUTE_NAME_CONACTION); if (!start && conactValue != null) { if (ATTR_CONACTION_VALUE_PUSHBEFORE.equals(conactValue)) { if (pushcontentDocumentFragment.getChildNodes().getLength() != 0) { // there are redundant "pushbefore", create a new pushcontent and emit a warning message. if (pushcontentWriter != null) { try { pushcontentWriter.close(); } catch (final XMLStreamException e) { throw new SAXException(e); } } pushcontentWriter = getXMLStreamWriter(); logger.warn( MessageUtils.getInstance().getMessage("DOTJ044W").setLocation(atts).toString()); } start = true; level = 1; putElement(name, atts, true); pushType = ATTR_CONACTION_VALUE_PUSHBEFORE; } else if (ATTR_CONACTION_VALUE_PUSHAFTER.equals(conactValue)) { start = true; level = 1; if (target == null) { logger.error( MessageUtils.getInstance().getMessage("DOTJ039E").setLocation(atts).toString()); } else { putElement(name, atts, true); pushType = ATTR_CONACTION_VALUE_PUSHAFTER; } } else if (ATTR_CONACTION_VALUE_PUSHREPLACE.equals(conactValue)) { start = true; level = 1; target = toURI(atts.getValue(ATTRIBUTE_NAME_CONREF)); if (target == null) { logger.error( MessageUtils.getInstance().getMessage("DOTJ040E").setLocation(atts).toString()); } else { pushType = ATTR_CONACTION_VALUE_PUSHREPLACE; putElement(name, atts, true); } } else if (ATTR_CONACTION_VALUE_MARK.equals(conactValue)) { target = toURI(atts.getValue(ATTRIBUTE_NAME_CONREF)); if (target == null) { logger.error( MessageUtils.getInstance().getMessage("DOTJ068E").setLocation(atts).toString()); } if (target != null && pushcontentDocumentFragment != null && pushcontentDocumentFragment.getChildNodes().getLength() > 0 && ATTR_CONACTION_VALUE_PUSHBEFORE.equals(pushType)) { // pushcontent != null means it is pushbefore action // we need to add target and content to pushtable if (pushcontentWriter != null) { try { pushcontentWriter.close(); } catch (final XMLStreamException e) { throw new SAXException(e); } } addtoPushTable(target, replaceContent(pushcontentDocumentFragment), pushType); pushcontentWriter = getXMLStreamWriter(); target = null; pushType = null; } } } // else if (pushcontent != null && pushcontent.length() > 0 && level == 0) { // if there is no element with conaction="mark" after // one with conaction="pushbefore", report syntax error // } }