/* ******************************************************************************
* Copyright (c) 2006-2012 XMind Ltd. and others.
*
* This file is a part of XMind 3. XMind releases 3 and
* above are dual-licensed under the Eclipse Public License (EPL),
* which is available at http://www.eclipse.org/legal/epl-v10.html
* and the GNU Lesser General Public License (LGPL),
* which is available at http://www.gnu.org/licenses/lgpl.html
* See http://www.xmind.net/license.html for details.
*
* Contributors:
* XMind Ltd. - initial API and implementation
*******************************************************************************/
package org.xmind.core.internal.dom;
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.Element;
import org.w3c.dom.Node;
import org.xmind.core.IAdaptable;
import org.xmind.core.IResourceRef;
import org.xmind.core.ISheet;
import org.xmind.core.ITopic;
import org.xmind.core.ITopicExtensionElement;
import org.xmind.core.IWorkbook;
import org.xmind.core.internal.TopicExtension;
import org.xmind.core.util.DOMUtils;
public class TopicExtensionImpl extends TopicExtension
implements INodeAdaptableProvider {
private Element implementation;
private TopicImpl topic;
private TopicExtensionElementImpl content;
private Map<Element, TopicExtensionElementImpl> eleMap = new HashMap<Element, TopicExtensionElementImpl>();
public TopicExtensionImpl(Element implementation, TopicImpl topic) {
this.implementation = implementation;
this.topic = topic;
}
public Element getImplementation() {
return implementation;
}
public boolean equals(Object obj) {
if (obj == this)
return true;
if (obj == null || !(obj instanceof TopicExtensionImpl))
return false;
TopicExtensionImpl that = (TopicExtensionImpl) obj;
return this.implementation == that.implementation;
}
public int hashCode() {
return implementation.hashCode();
}
public String toString() {
return "{topic-extension:" + getProviderName() + "}"; //$NON-NLS-1$ //$NON-NLS-2$
}
private Element getContentElement() {
return DOMUtils.ensureChildElement(implementation,
DOMConstants.TAG_CONTENT);
}
public ITopicExtensionElement getContent() {
if (content == null) {
content = new TopicExtensionElementImpl(getContentElement(), topic,
this);
registerElement(content);
}
return content;
}
public String getProviderName() {
return implementation.getAttribute(DOMConstants.ATTR_PROVIDER);
}
public ITopic getParent() {
return topic;
}
public ISheet getOwnedSheet() {
return topic.getOwnedSheet();
}
public IWorkbook getOwnedWorkbook() {
return topic.getOwnedWorkbook();
}
public boolean isOrphan() {
return DOMUtils.isOrphanNode(implementation);
}
public <T> T getAdapter(Class<T> adapter) {
if (adapter.isAssignableFrom(Element.class))
return adapter.cast(implementation);
return super.getAdapter(adapter);
}
private Element getRefsElement() {
return DOMUtils.getFirstChildElementByTag(implementation,
TAG_RESOURCE_REFS);
}
public void addResourceRef(IResourceRef ref) {
Element refEle = ((ResourceRefImpl) ref).getImplementation();
Element refsEle = DOMUtils.ensureChildElement(implementation,
TAG_RESOURCE_REFS);
Node n = refsEle.appendChild(refEle);
if (n != null) {
if (!isOrphan()) {
((ResourceRefImpl) ref).addNotify(topic.getRealizedWorkbook());
}
//TODO fire resource ref added
topic.updateModificationInfo();
}
}
public List<IResourceRef> getResourceRefs() {
Element refsEle = getRefsElement();
if (refsEle != null)
return DOMUtils.getChildList(refsEle, DOMConstants.TAG_RESOURCE_REF,
((WorkbookImpl) topic.getOwnedWorkbook())
.getAdaptableRegistry());
return EMPTY_REFS;
}
public void removeResourceRef(IResourceRef ref) {
Element refsEle = getRefsElement();
if (refsEle == null)
return;
Element refEle = ((ResourceRefImpl) ref).getImplementation();
if (refEle.getParentNode() == refsEle) {
((ResourceRefImpl) ref).removeNotify(topic.getRealizedWorkbook());
Node n = refsEle.removeChild(refEle);
if (!refsEle.hasChildNodes())
implementation.removeChild(refsEle);
if (n != null) {
//TODO fire resource ref removed
topic.updateModificationInfo();
}
}
}
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);
}
}
protected void registerElement(TopicExtensionElementImpl element) {
eleMap.put(element.getImplementation(), element);
}
protected void unregisterElement(TopicExtensionElementImpl element) {
eleMap.remove(element.getImplementation());
}
protected TopicExtensionElementImpl getElement(Element impl) {
if (impl == implementation)
return null;
TopicExtensionElementImpl ele = eleMap.get(impl);
if (ele == null) {
ele = new TopicExtensionElementImpl(impl, topic, this);
registerElement(ele);
}
return ele;
}
public IAdaptable getAdaptable(Node node) {
if (node instanceof Element)
return getElement((Element) node);
return null;
}
}