/* ******************************************************************************
* 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 java.util.HashMap;
import java.util.Map;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xmind.core.IAdaptable;
/**
* @author Frank Shaka
*
*/
public class NodeAdaptableRegistry implements INodeAdaptableProvider {
private Document defaultDocument;
private INodeAdaptableFactory factory;
private Map<IDKey, IAdaptable> idMap = new HashMap<IDKey, IAdaptable>();
private Map<Node, IAdaptable> nodeMap = new HashMap<Node, IAdaptable>();
/**
* Used to retrieve adaptable object by ID.
*/
private IDKey key = new IDKey(null, null);
/**
*
*/
public NodeAdaptableRegistry(Document defaultDocument,
INodeAdaptableFactory factory) {
this.defaultDocument = defaultDocument;
this.factory = factory;
}
public IAdaptable getAdaptable(String id) {
return getAdaptable(id, defaultDocument);
}
public IAdaptable getAdaptable(String id, Document document) {
IAdaptable a = getAdaptableById(id, document);
if (a == null) {
Element element = document.getElementById(id);
if (element != null) {
a = getAdaptableByNode(element);
if (a == null) {
a = createAdaptable(element);
}
if (a != null) {
registerByNode(a, element);
registerById(a, id, document);
}
}
}
return a;
}
public IAdaptable getAdaptable(Node node) {
IAdaptable a = nodeMap.get(node);
if (a == null) {
a = createAdaptable(node);
if (a != null) {
registerByNode(a, node);
String id = getId(node);
if (id != null) {
registerById(a, id, node.getOwnerDocument());
}
}
}
return a;
}
public void register(IAdaptable adaptable, String id) {
register(adaptable, id, defaultDocument);
}
public void register(IAdaptable adaptable, String id, Document document) {
registerById(adaptable, id, document);
Element element = document.getElementById(id);
if (element != null) {
registerByNode(adaptable, element);
}
}
public void register(IAdaptable adaptable, Node node) {
registerByNode(adaptable, node);
String id = getId(node);
if (id != null) {
registerById(adaptable, id, node.getOwnerDocument());
}
}
public void unregister(IAdaptable adaptable, String id) {
unregister(adaptable, id, defaultDocument);
}
public void unregister(IAdaptable adaptable, String id, Document document) {
unregisterById(adaptable, id, document);
Element element = document.getElementById(id);
if (element != null) {
unregisterByNode(adaptable, element);
}
}
public void unregister(IAdaptable adaptable, Node node) {
unregisterByNode(adaptable, node);
String id = getId(node);
if (id != null) {
unregisterById(adaptable, id, node.getOwnerDocument());
}
}
private String getId(Node node) {
if (node.getNodeType() == Node.ELEMENT_NODE) {
Node v = node.getAttributes().getNamedItem(DOMConstants.ATTR_ID);
if (v != null) {
String id = v.getNodeValue();
if (id != null && !"".equals(id)) { //$NON-NLS-1$
return id;
}
}
}
return null;
}
/**
* @param id
* @param document
* @return
*/
private IDKey getIDKey(String id, Document document) {
key.id = id;
key.document = document;
return key;
}
/**
* @param id
* @param document
* @return
*/
private IDKey createIDKey(String id, Document document) {
return new IDKey(document, id);
}
public IAdaptable getAdaptableById(String id, Document document) {
return idMap.get(getIDKey(id, document));
}
public IAdaptable getAdaptableByNode(Node node) {
return nodeMap.get(node);
}
public void registerById(IAdaptable adaptable, String id, Document document) {
idMap.put(createIDKey(id, document), adaptable);
}
public void registerByNode(IAdaptable adaptable, Node node) {
nodeMap.put(node, adaptable);
}
public void unregisterById(IAdaptable adaptable, String id,
Document document) {
IDKey key = getIDKey(id, document);
IAdaptable a = idMap.get(key);
if (a == adaptable || (a != null && a.equals(adaptable))) {
idMap.remove(key);
}
}
public void unregisterByNode(IAdaptable adaptable, Node node) {
IAdaptable a = nodeMap.get(node);
if (a == adaptable || (a != null && a.equals(adaptable))) {
nodeMap.remove(node);
}
}
/**
* @param element
* @return
*/
private IAdaptable createAdaptable(Node element) {
return factory == null ? null : factory.createAdaptable(element);
}
}