package jp.aonir.fuzzyxml.internal; import java.util.ArrayList; import java.util.List; import jp.aonir.fuzzyxml.FuzzyXMLAttribute; import jp.aonir.fuzzyxml.FuzzyXMLCDATA; import jp.aonir.fuzzyxml.FuzzyXMLComment; import jp.aonir.fuzzyxml.FuzzyXMLDocType; import jp.aonir.fuzzyxml.FuzzyXMLDocument; import jp.aonir.fuzzyxml.FuzzyXMLElement; import jp.aonir.fuzzyxml.FuzzyXMLNode; import jp.aonir.fuzzyxml.FuzzyXMLProcessingInstruction; import jp.aonir.fuzzyxml.FuzzyXMLText; import jp.aonir.fuzzyxml.event.FuzzyXMLModifyEvent; import jp.aonir.fuzzyxml.event.FuzzyXMLModifyListener; public class FuzzyXMLDocumentImpl implements FuzzyXMLDocument { private boolean _isHTML = false; private FuzzyXMLElement _root; private FuzzyXMLDocType _docType; private List<FuzzyXMLModifyListener> _listeners = new ArrayList<FuzzyXMLModifyListener>(); public FuzzyXMLDocumentImpl(FuzzyXMLElement root, FuzzyXMLDocType docType) { super(); this._root = root; this._docType = docType; if (this._root != null) { ((FuzzyXMLElementImpl) this._root).setDocument(this); setDocument(this._root); } if (this._docType != null) { ((AbstractFuzzyXMLNode) this._docType).setDocument(this); } } public void setHTML(boolean isHTML) { this._isHTML = isHTML; } public boolean isHTML() { return this._isHTML; } private void setDocument(FuzzyXMLElement element) { FuzzyXMLNode[] children = element.getChildren(); for (int i = 0; i < children.length; i++) { ((AbstractFuzzyXMLNode) children[i]).setDocument(this); if (children[i] instanceof FuzzyXMLElement) { setDocument((FuzzyXMLElement) children[i]); } } FuzzyXMLAttribute[] attr = element.getAttributes(); for (int i = 0; i < attr.length; i++) { ((AbstractFuzzyXMLNode) attr[i]).setDocument(this); } } public FuzzyXMLComment createComment(String value) { return new FuzzyXMLCommentImpl(value); } public FuzzyXMLElement createElement(String name) { return new FuzzyXMLElementImpl(name); } public FuzzyXMLAttribute createAttribute(String namespace, String name) { return new FuzzyXMLAttributeImpl(namespace, name, null, null); } public FuzzyXMLText createText(String value) { return new FuzzyXMLTextImpl(value); } public FuzzyXMLCDATA createCDATASection(String value) { return new FuzzyXMLCDATAImpl(value); } public FuzzyXMLProcessingInstruction createProcessingInstruction(String name, String data) { return new FuzzyXMLProcessingInstructionImpl(name, data); } public FuzzyXMLElement getDocumentElement() { return _root; } public FuzzyXMLDocType getDocumentType() { return _docType; } public FuzzyXMLElement getElementByOffset(int offset) { if (_root == null) { return null; } List<FuzzyXMLElement> matches = new ArrayList<FuzzyXMLElement>(); matches.add(_root); matchOffsetElement(_root, matches, offset); FuzzyXMLElement find = null; for (int i = 0; i < matches.size(); i++) { FuzzyXMLElement element = matches.get(i); if (find == null || find.getLength() >= element.getLength()) { find = element; } } return find; } private void matchOffsetElement(FuzzyXMLElement element, List<FuzzyXMLElement> matches, int offset) { FuzzyXMLNode[] nodes = element.getChildren(); for (int i = 0; i < nodes.length; i++) { if (nodes[i] instanceof FuzzyXMLElement) { FuzzyXMLElement e = (FuzzyXMLElement) nodes[i]; if (e.getOffset() <= offset && offset <= e.getOffset() + e.getLength()) { matches.add(e); matchOffsetElement(e, matches, offset); } } } } public void addModifyListener(FuzzyXMLModifyListener listener) { _listeners.add(listener); } public void removeModifyListener(FuzzyXMLModifyListener listener) { _listeners.remove(listener); } /** * @param newText * @param offset * @param length */ public void fireModifyEvent(String newText, int offset, int length) { FuzzyXMLModifyEvent evt = new FuzzyXMLModifyEvent(newText, offset, length); for (int i = 0; i < _listeners.size(); i++) { FuzzyXMLModifyListener listener = _listeners.get(i); listener.modified(evt); } } /** * @param offset * @param append */ public void appendOffset(FuzzyXMLElement parent, int offset, int append) { appendOffsetForElement((FuzzyXMLElementImpl) _root, offset, append); appendLengthForParent((FuzzyXMLElementImpl) parent, append); } private void appendOffsetForElement(FuzzyXMLElementImpl element, int offset, int append) { FuzzyXMLNode[] children = element.getChildren(); for (int i = 0; i < children.length; i++) { if (children[i].getOffset() >= offset) { ((AbstractFuzzyXMLNode) children[i]).setOffset(children[i].getOffset() + append); } if (children[i] instanceof FuzzyXMLElementImpl) { appendOffsetForElement((FuzzyXMLElementImpl) children[i], offset, append); } } FuzzyXMLAttribute[] attr = element.getAttributes(); for (int i = 0; i < attr.length; i++) { if (attr[i].getOffset() >= offset) { ((AbstractFuzzyXMLNode) attr[i]).setOffset(attr[i].getOffset() + append); } } } private void appendLengthForParent(FuzzyXMLElementImpl parent, int appendLength) { parent.setLength(parent.getLength() + appendLength); if (parent.getParentNode() != null) { appendLengthForParent((FuzzyXMLElementImpl) parent.getParentNode(), appendLength); } } }