package org.xmind.core.internal.dom; import static org.xmind.core.internal.dom.DOMConstants.ATTR_PROVIDER; import static org.xmind.core.internal.dom.DOMConstants.TAG_CONTENT; import static org.xmind.core.internal.dom.DOMConstants.TAG_RESOURCE_REF; import static org.xmind.core.internal.dom.DOMConstants.TAG_RESOURCE_REFS; import java.util.HashMap; import java.util.List; import java.util.Map; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.xmind.core.IAdaptable; import org.xmind.core.IResourceRef; import org.xmind.core.IWorkbook; import org.xmind.core.IWorkbookExtensionElement; import org.xmind.core.internal.WorkbookExtension; import org.xmind.core.util.DOMUtils; /** * @author Jason Wong */ public class WorkbookExtensionImpl extends WorkbookExtension implements INodeAdaptableProvider { private Map<Element, WorkbookExtensionElementImpl> eleMap = new HashMap<Element, WorkbookExtensionElementImpl>(); private Document implementation; private WorkbookImpl workbook; private WorkbookExtensionElementImpl content; public WorkbookExtensionImpl(Document implementation, WorkbookImpl workbook) { this.implementation = implementation; this.workbook = workbook; init(); } private void init() { Element e = getExtensionElement(); for (NS ns : NS.values()) { if (ns.getPrefix().equals(e.getTagName())) NS.setNS(ns, e); } } private Element getExtensionElement() { return implementation.getDocumentElement(); } protected void addNotify(WorkbookImpl workbook) { for (IResourceRef ref : getResourceRefs()) ((ResourceRefImpl) ref).addNotify(workbook); } protected void removeNotify(WorkbookImpl workbook) { for (IResourceRef ref : getResourceRefs()) ((ResourceRefImpl) ref).removeNotify(workbook); } public Document getImplementation() { return implementation; } public String getProviderName() { return getExtensionElement().getAttribute(ATTR_PROVIDER); } public IWorkbookExtensionElement getContent() { if (content == null) { content = new WorkbookExtensionElementImpl(getContentElement(), workbook, this); registerElement(content); } return content; } private Element getContentElement() { return DOMUtils.ensureChildElement(getExtensionElement(), TAG_CONTENT); } public List<IResourceRef> getResourceRefs() { Element refsEle = getRefsElement(); if (refsEle != null) return DOMUtils.getChildList(refsEle, TAG_RESOURCE_REF, workbook.getAdaptableRegistry()); return EMPTY_REFS; } public IResourceRef getResourceRef(String resourceId) { if (resourceId != null && !"".equals(resourceId)) { //$NON-NLS-1$ for (IResourceRef ref : getResourceRefs()) { if (resourceId.equals(ref.getResourceId())) return ref; } } return null; } public void addResourceRef(IResourceRef ref) { importResourceRef(ref); Element refEle = ((ResourceRefImpl) ref).getImplementation(); Element refsEle = DOMUtils.ensureChildElement(getExtensionElement(), TAG_RESOURCE_REFS); Node n = refsEle.appendChild(refEle); if (n != null) { if (!isOrphan()) ((ResourceRefImpl) ref).addNotify(workbook); } workbook.updateModificationInfo(); } private void importResourceRef(IResourceRef ref) { Element oldValue = ((ResourceRefImpl) ref).getImplementation(); Element newValue = implementation.createElement(oldValue.getTagName()); newValue.setAttribute(DOMConstants.ATTR_RESOURCE_ID, ref.getResourceId()); newValue.setAttribute(DOMConstants.ATTR_TYPE, ref.getType()); ((ResourceRefImpl) ref).setImplementation(newValue); } public void removeResourceRef(IResourceRef ref) { Element refsEle = getRefsElement(); if (refsEle == null) return; Element refEle = ((ResourceRefImpl) ref).getImplementation(); if (refEle.getParentNode() == refsEle) { ((ResourceRefImpl) ref).removeNotify(workbook); Node n = refsEle.removeChild(refEle); if (!refsEle.hasChildNodes()) getExtensionElement().removeChild(refsEle); if (n != null) workbook.updateModificationInfo(); } } private Element getRefsElement() { return DOMUtils.getFirstChildElementByTag(getExtensionElement(), TAG_RESOURCE_REFS); } public IWorkbook getOwnedWorkbook() { return workbook; } public IAdaptable getAdaptable(Node node) { if (node instanceof Element) return getElement((Element) node); return null; } public <T> T getAdapter(Class<T> adapter) { if (adapter.isAssignableFrom(Element.class)) return adapter.cast(getImplementation()); return super.getAdapter(adapter); } protected WorkbookExtensionElementImpl getElement(Element impl) { if (impl == getExtensionElement()) return null; WorkbookExtensionElementImpl ele = eleMap.get(impl); if (ele == null) { ele = new WorkbookExtensionElementImpl(impl, workbook, this); registerElement(ele); } return ele; } protected void registerElement(WorkbookExtensionElementImpl element) { eleMap.put(element.getImplementation(), element); } protected void unregisterElement(WorkbookExtensionElementImpl element) { eleMap.remove(element.getImplementation()); } public boolean isOrphan() { return DOMUtils.isOrphanNode(implementation); } @Override public boolean equals(Object obj) { if (obj == this) return true; if (obj == null || !(obj instanceof WorkbookExtensionImpl)) return false; WorkbookExtensionImpl that = (WorkbookExtensionImpl) obj; return this.implementation == that.implementation; } @Override public int hashCode() { return implementation.hashCode(); } @Override public String toString() { return "{workbook-extension:" + getProviderName() + "}"; //$NON-NLS-1$ //$NON-NLS-2$ } }