/* ******************************************************************************
* 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.ATTR_ID;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xmind.core.IAdaptable;
import org.xmind.core.internal.ElementRegistry;
public class NodeAdaptableProvider implements INodeAdaptableProvider {
private ElementRegistry registry;
private INodeAdaptableFactory factory;
private Document primaryDocument;
public NodeAdaptableProvider(ElementRegistry registry,
INodeAdaptableFactory factory, Document primaryDocument) {
this.registry = registry;
this.factory = factory;
this.primaryDocument = primaryDocument;
}
private Object getID(Node node) {
if (node instanceof Element) {
Element e = (Element) node;
String id = e.getAttribute(ATTR_ID);
if (id != null && !"".equals(id)) { //$NON-NLS-1$
Document doc = node.getNodeType() == Node.DOCUMENT_NODE ? (Document) node
: node.getOwnerDocument();
if (doc.equals(primaryDocument)) {
return id;
}
return new IDKey(doc, id);
}
}
return null;
}
/**
* Get the object adaptable to the DOM node. If no existing one is found, a
* new proper one will be created and retruned.
*
* @param node
* A DOM node
* @return the adaptable object
*/
public IAdaptable getAdaptable(Node node) {
if (node == null)
return null;
/*
* first, if the element has an ID, we look through the registry to see
* if there's any existing element with that ID
*/
Object id = getID(node);
if (id != null) {
Object e = registry.getElement(id);
if (e != null && e instanceof IAdaptable)
return (IAdaptable) e;
}
/*
* second, look through the registry using the element itself as the key
*/
Object e = registry.getElement(node);
if (e instanceof IAdaptable)
return (IAdaptable) e;
/*
* if no found, create a new adapter wrapping the DOM element
*/
IAdaptable adaptable = createAdaptable(node);
if (adaptable != null) {
register(adaptable, node);
return adaptable;
}
return null;
}
private void register(IAdaptable adapter, Node node) {
Object id = getID(node);
if (id != null) {
registry.registerByKey(id, adapter);
}
registry.registerByKey(node, adapter);
}
private IAdaptable createAdaptable(Node node) {
IAdaptable adaptable = factory.createAdaptable(node);
if (adaptable != null && adaptable.getAdapter(Node.class) == node)
return adaptable;
return null;
}
}