/************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
 * 
 * Copyright 2008, 2010 Oracle and/or its affiliates. All rights reserved.
 * 
 * Use is subject to license terms.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy
 * of the License at http://www.apache.org/licenses/LICENSE-2.0. You can also
 * obtain a copy of the License at http://odftoolkit.org/docs/license.txt
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * 
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ************************************************************************/
package org.odftoolkit.odfdom.pkg;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;

import org.apache.xerces.dom.DocumentImpl;
import org.odftoolkit.odfdom.dom.OdfContentDom;
import org.odftoolkit.odfdom.dom.OdfMetaDom;
import org.odftoolkit.odfdom.dom.OdfSchemaDocument;
import org.odftoolkit.odfdom.dom.OdfSettingsDom;
import org.odftoolkit.odfdom.dom.OdfStylesDom;
import org.odftoolkit.odfdom.dom.rdfa.BookmarkRDFMetadataExtractor;
import org.odftoolkit.odfdom.pkg.manifest.OdfManifestDom;
import org.odftoolkit.odfdom.pkg.rdfa.DOMRDFaParser;
import org.odftoolkit.odfdom.pkg.rdfa.JenaSink;
import org.odftoolkit.odfdom.pkg.rdfa.MultiContentHandler;
import org.odftoolkit.odfdom.pkg.rdfa.SAXRDFaParser;
import org.odftoolkit.odfdom.pkg.rdfa.Util;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;

import org.apache.jena.rdf.model.Model;

/**
 * The DOM representation of an XML file within the ODF document.
 */
public class OdfFileDom extends DocumentImpl implements NamespaceContext {

	private static final long serialVersionUID = 766167617530147000L;
	protected String mPackagePath;
	protected OdfPackageDocument mPackageDocument;
	protected OdfPackage mPackage;
	protected XPath mXPath;
	protected Map<String, String> mUriByPrefix;
	protected Map<String, String> mPrefixByUri;
	/** Contains only the duplicate prefix. 
	 * The primary hold by mPrefixByUri still have to be added
	 */
	protected Map<String, Set<String>> mDuplicatePrefixesByUri;
	/**
	* The cache of in content metadata: key: a Node in the dom ; value: the
	* Jena RDF model of triples of the Node
	*/
	protected Map<Node, Model> inCententMetadataCache;

	protected JenaSink sink;

	/**
	 * Creates the DOM representation of an XML file of an Odf document.
	 * 
	 * @param packageDocument
	 *            the document the XML files belongs to
	 * @param packagePath
	 *            the internal package path to the XML file
	 */
	protected OdfFileDom(OdfPackageDocument packageDocument, String packagePath) {
		super(false);
		if (packageDocument != null && packagePath != null) {
			mPackageDocument = packageDocument;
			mPackage = packageDocument.getPackage();
			mPackagePath = packagePath;
			mUriByPrefix = new HashMap<String, String>();
			mPrefixByUri = new HashMap<String, String>();
			mDuplicatePrefixesByUri = new HashMap<String, Set<String>>();
			inCententMetadataCache = new IdentityHashMap<Node, Model>();
			initialize();
			// Register every DOM to OdfPackage,
			// so a package close might save this DOM (similar as OdfDocumentPackage)
			this.addDomToCache(mPackage, packagePath);
		} else {
			throw new IllegalArgumentException("Arguments are not allowed to be NULL for OdfFileDom constructor!");
		}
	}

	/**
	* Creates the DOM representation of an XML file of an Odf document.
	*
	* @param pkg
	* the package the XML files belongs to
	* @param packagePath
	* the internal package path to the XML file
	*/
	protected OdfFileDom(OdfPackage pkg, String packagePath) {
		super(false);
		if (pkg != null && packagePath != null) {
			mPackageDocument = null;
			mPackage = pkg;
			mPackagePath = packagePath;
			mUriByPrefix = new HashMap<String, String>();
			mPrefixByUri = new HashMap<String, String>();
			mDuplicatePrefixesByUri = new HashMap<String, Set<String>>();
			inCententMetadataCache = new HashMap<Node, Model>();
			initialize();
			// Register every DOM to OdfPackage,
			// so a package close might save this DOM (similar as
			// OdfDocumentPackage)
			addDomToCache(mPackage, packagePath);
		} else {
			throw new IllegalArgumentException("Arguments are not allowed to be NULL for OdfFileDom constructor!");
		}
	}

	/** 
	 *Adds the document to the pool of open documents of the package.
	 *A document of a certain path is opened only once to avoid data duplication.
	 */
	private void addDomToCache(OdfPackage pkg, String internalPath) {
		pkg.cacheDom(this, internalPath);
	}

	public static OdfFileDom newFileDom(OdfPackageDocument packageDocument, String packagePath) {
		OdfFileDom newFileDom = null;
		// before creating a new dom, make sure that there no DOM opened for this file already
		Document existingDom = packageDocument.getPackage().getCachedDom(packagePath);
		if (existingDom == null) {
			// ToDo: bug 264 - register OdfFileDom to this class
			if (packagePath.equals("content.xml") || packagePath.endsWith("/content.xml")) {
				newFileDom = new OdfContentDom((OdfSchemaDocument) packageDocument, packagePath);
			} else if (packagePath.equals("styles.xml") || packagePath.endsWith("/styles.xml")) {
				newFileDom = new OdfStylesDom((OdfSchemaDocument) packageDocument, packagePath);
			} else if (packagePath.equals("meta.xml") || packagePath.endsWith("/meta.xml")) {
				newFileDom = new OdfMetaDom((OdfSchemaDocument) packageDocument, packagePath);
			} else if (packagePath.equals("settings.xml") || packagePath.endsWith("/settings.xml")) {
				newFileDom = new OdfSettingsDom((OdfSchemaDocument) packageDocument, packagePath);
			} else if (packagePath.equals("META-INF/manifest.xml") || packagePath.endsWith("/META-INF/manifest.xml")) {
				newFileDom = new OdfManifestDom((OdfSchemaDocument) packageDocument, packagePath);
			} else {
				newFileDom = new OdfFileDom(packageDocument, packagePath);
			}
		} else {
			if (existingDom instanceof OdfFileDom) {
				newFileDom = (OdfFileDom) existingDom;
//ToDO: Issue 264 - Otherwise if NOT an OdfFileDom serialize old DOM AND CREATE A NEW ONE?!
// Or shall we always reference to the dom, than we can not inherit from Document? Pro/Con?s
//			}else{
//				// Create an OdfFileDOM from an existing DOM
//				newFileDom =
			}

		}
		return newFileDom;
	}

	public static OdfFileDom newFileDom(OdfPackage pkg, String packagePath) {
		OdfFileDom newFileDom = null;
		// before creating a new dom, make sure that there no DOM opened for this file already
		Document existingDom = pkg.getCachedDom(packagePath);
		if (existingDom == null) {
			if (packagePath.equals("META-INF/manifest.xml") || packagePath.endsWith("/META-INF/manifest.xml")) {
				newFileDom = new OdfManifestDom(pkg, packagePath);
			} else {
				newFileDom = new OdfFileDom(pkg, packagePath);
			}
		} else {
			if (existingDom instanceof OdfFileDom) {
				newFileDom = (OdfFileDom) existingDom;
//ToDO: Issue 264 - Otherwise if NOT an OdfFileDom serialize old DOM AND CREATE A NEW ONE?!
// Or shall we always reference to the dom, than we can not inherit from Document? Pro/Con?s
//			}else{
//				// Create an OdfFileDOM from an existing DOM
//				newFileDom =
			}

		}
		return newFileDom;
	}
	
	protected void initialize() {
		InputStream fileStream = null;
		try {
			fileStream = mPackage.getInputStream(mPackagePath);
			if (fileStream != null) {
				XMLReader xmlReader = mPackage.getXMLReader();
				OdfFileSaxHandler odf = new OdfFileSaxHandler(this);
				String baseUri = Util.getRDFBaseUri(mPackage.getBaseURI(),mPackagePath);
				sink = new JenaSink(this);
				odf.setSink(sink);
				SAXRDFaParser rdfa = SAXRDFaParser.createInstance(sink);
				rdfa.setBase(baseUri);
				// the file is parsed by ODF ContentHandler, and then RDFa ContentHandler
				MultiContentHandler multi = new MultiContentHandler(odf, rdfa);
				xmlReader.setContentHandler(multi);
				InputSource xmlSource = new InputSource(fileStream);
				xmlReader.parse(xmlSource);
			}
		} catch (Exception ex) {
			Logger.getLogger(OdfFileDom.class.getName()).log(Level.SEVERE, null, ex);
		} finally {
			try {
				if (fileStream != null) {
					fileStream.close();
				}
			} catch (IOException ex) {
				Logger.getLogger(OdfFileDom.class.getName()).log(Level.SEVERE, null, ex);
			}
		}
	}

	/**
	 * Retrieves the <code>OdfPackageDocument</code> of the XML file.
	 * A package document is usually represented as a directory with a mediatype.
	 *
	 * @return The document holding the XML file.
	 *
	 */
	public OdfPackageDocument getDocument() {
		return mPackageDocument;
	}

	/**
	 * Retrieves the <code>String</code> of Package Path
	 * 
	 * @return The path of the XML file relative to the package root
	 */
	public String getPackagePath() {
		return mPackagePath;
	}

	/**
	 * Retrieves the ODF root element.
	 *
	 * @return The <code>OdfElement</code> being the root of the document.
	 */
	public OdfElement getRootElement() {
		return (OdfElement) getDocumentElement();
	}

	/**
	 * Create ODF element with namespace uri and qname
	 *
	 * @param name The element name
	 *
	 */
	@Override
	public OdfElement createElement(String name) throws DOMException {
		return createElementNS(OdfName.newName(name));
	}

	/**
	 * Create ODF element with namespace uri and qname
	 *
	 * @param nsuri The namespace uri
	 * @param qname The element qname
	 *
	 */
	@Override
	public OdfElement createElementNS(String nsuri, String qname) throws DOMException {
		return createElementNS(OdfName.newName(nsuri, qname));
	}

	/**
	 * Create ODF element with ODF name
	 * @param name The <code>OdfName</code>
	 * @return The <code>OdfElement</code>
	 * @throws DOMException
	 */
	public OdfElement createElementNS(OdfName name) throws DOMException {
		return OdfXMLFactory.newOdfElement(this, name);
	}

	/**
	 * Create the ODF attribute with its name
	 *
	 * @param name  the attribute qname
	 * @return The <code>OdfAttribute</code>
	 * @throws  DOMException
	 */
	@Override
	public OdfAttribute createAttribute(String name) throws DOMException {
		return createAttributeNS(OdfName.newName(name));
	}

	/**
	 * Create the ODF attribute with namespace uri and qname
	 * 
	 * @param nsuri  The namespace uri
	 * @param qname  the attribute qname
	 * @return The <code>OdfAttribute</code>
	 * @throws  DOMException
	 */
	@Override
	public OdfAttribute createAttributeNS(String nsuri, String qname) throws DOMException {
		return createAttributeNS(OdfName.newName(nsuri, qname));
	}

	/**
	 * Create the ODF attribute with ODF name
	 * @param name The <code>OdfName</code>
	 * @return  The <code>OdfAttribute</code>
	 * @throws DOMException
	 */
	public OdfAttribute createAttributeNS(OdfName name) throws DOMException {
		return OdfXMLFactory.newOdfAttribute(this, name);
	}

	@SuppressWarnings("unchecked")
	public <T extends OdfElement> T newOdfElement(Class<T> clazz) {
		//return (T) OdfXMLFactory.getNodeFromClass(this, clazz);
		try {
			Field fname = clazz.getField("ELEMENT_NAME");
			OdfName name = (OdfName) fname.get(null);
			return (T) createElementNS(name);
		} catch (Exception ex) {
			if (ex instanceof RuntimeException) {
				throw (RuntimeException) ex;
			}
			return null;
		}
	}

	@Override
	public String toString() {
		return ((OdfElement) this.getDocumentElement()).toString();
	}

	// JDK Namespace handling
	/**
	 * Create an XPath instance to select one or more nodes from an ODF document.
	 * Therefore the namespace context is set to the OdfNamespace
	 * @return an XPath instance with namespace context set to include the standard
	 * ODFDOM prefixes.
	 */
	public XPath getXPath() {
		if (mXPath == null) {
			mXPath = XPathFactory.newInstance().newXPath();
		}
		return mXPath;
	}

	/**
	 * <p>Get Namespace URI bound to a prefix in the current scope (the XML file).</p>
	 *
	 * <p>When requesting a Namespace URI by prefix, the following
	 * table describes the returned Namespace URI value for all
	 * possible prefix values:</p>
	 *
	 * <table border="2" rules="all" cellpadding="4">
	 *   <thead>
	 *     <tr>
	 *       <td align="center" colspan="2">
	 *         <code>getNamespaceURI(prefix)</code>
	 *         return value for specified prefixes
	 *       </td>
	 *     </tr>
	 *     <tr>
	 *       <td>prefix parameter</td>
	 *       <td>Namespace URI return value</td>
	 *     </tr>
	 *   </thead>
	 *   <tbody>
	 *     <tr>
	 *       <td><code>DEFAULT_NS_PREFIX</code> ("")</td>
	 *       <td>default Namespace URI in the current scope or
	 *         <code>{@link
	 *         javax.xml.XMLConstants#NULL_NS_URI XMLConstants.NULL_NS_URI("")}
	 *         </code>
	 *         when there is no default Namespace URI in the current scope</td>
	 *     </tr>
	 *     <tr>
	 *       <td>bound prefix</td>
	 *       <td>Namespace URI bound to prefix in current scope</td>
	 *     </tr>
	 *     <tr>
	 *       <td>unbound prefix</td>
	 *       <td>
	 *         <code>{@link
	 *         javax.xml.XMLConstants#NULL_NS_URI XMLConstants.NULL_NS_URI("")}
	 *         </code>
	 *       </td>
	 *     </tr>
	 *     <tr>
	 *       <td><code>XMLConstants.XML_NS_PREFIX</code> ("xml")</td>
	 *       <td><code>XMLConstants.XML_NS_URI</code>
	 *           ("http://www.w3.org/XML/1998/namespace")</td>
	 *     </tr>
	 *     <tr>
	 *       <td><code>XMLConstants.XMLNS_ATTRIBUTE</code> ("xmlns")</td>
	 *       <td><code>XMLConstants.XMLNS_ATTRIBUTE_NS_URI</code>
	 *         ("http://www.w3.org/2000/xmlns/")</td>
	 *     </tr>
	 *     <tr>
	 *       <td><code>null</code></td>
	 *       <td><code>IllegalArgumentException</code> is thrown</td>
	 *     </tr>
	 *    </tbody>
	 * </table>
	 *
	 * @param prefix prefix to look up
	 *
	 * @return Namespace URI bound to prefix in the current scope
	 *
	 * @throws IllegalArgumentException When <code>prefix</code> is
	 *   <code>null</code>
	 */
	public String getNamespaceURI(String prefix) {
		String nsURI = null;
		nsURI = mUriByPrefix.get(prefix);
		if (nsURI == null) {
			// look in Duplicate URI prefixes
			Set<String> urisWithDuplicatePrefixes = this.mDuplicatePrefixesByUri.keySet();
			for (String aURI : urisWithDuplicatePrefixes) {
				Set<String> prefixes = this.mDuplicatePrefixesByUri.get(aURI);
				// check if requested prefix exists in hashset
				if (prefixes.contains(prefix)) {
					nsURI = aURI;
					break;
				}
			}
		}
		// there is a possibility it still may be null - so we check
		if (nsURI == null) {
			nsURI = XMLConstants.NULL_NS_URI;
		}
		return nsURI;
	}

	/**
	 * <p>Get prefix bound to Namespace URI in the current scope (the XML file).</p>
	 * <p>Multiple prefixes bound to Namespace URI will be normalized to the first prefix defined.</p>
	 *
	 * <p>When requesting a prefix by Namespace URI, the following
	 * table describes the returned prefix value for all Namespace URI
	 * values:</p>
	 *
	 * <table border="2" rules="all" cellpadding="4">
	 *   <thead>
	 *     <tr>
	 *       <th align="center" colspan="2">
	 *         <code>getPrefix(namespaceURI)</code> return value for
	 *         specified Namespace URIs
	 *       </th>
	 *     </tr>
	 *     <tr>
	 *       <th>Namespace URI parameter</th>
	 *       <th>prefix value returned</th>
	 *     </tr>
	 *   </thead>
	 *   <tbody>
	 *     <tr>
	 *       <td>&lt;default Namespace URI&gt;</td>
	 *       <td><code>XMLConstants.DEFAULT_NS_PREFIX</code> ("")
	 *       </td>
	 *     </tr>
	 *     <tr>
	 *       <td>bound Namespace URI</td>
	 *       <td>prefix bound to Namespace URI in the current scope,
	 *           if multiple prefixes are bound to the Namespace URI in
	 *           the current scope, a single arbitrary prefix, whose
	 *           choice is implementation dependent, is returned</td>
	 *     </tr>
	 *     <tr>
	 *       <td>unbound Namespace URI</td>
	 *       <td><code>null</code></td>
	 *     </tr>
	 *     <tr>
	 *       <td><code>XMLConstants.XML_NS_URI</code>
	 *           ("http://www.w3.org/XML/1998/namespace")</td>
	 *       <td><code>XMLConstants.XML_NS_PREFIX</code> ("xml")</td>
	 *     </tr>
	 *     <tr>
	 *       <td><code>XMLConstants.XMLNS_ATTRIBUTE_NS_URI</code>
	 *           ("http://www.w3.org/2000/xmlns/")</td>
	 *       <td><code>XMLConstants.XMLNS_ATTRIBUTE</code> ("xmlns")</td>
	 *     </tr>
	 *     <tr>
	 *       <td><code>null</code></td>
	 *       <td><code>IllegalArgumentException</code> is thrown</td>
	 *     </tr>
	 *   </tbody>
	 * </table>
	 *
	 * @param namespaceURI URI of Namespace to lookup
	 *
	 * @return prefix bound to Namespace URI in current context
	 *
	 * @throws IllegalArgumentException When <code>namespaceURI</code> is
	 *   <code>null</code>
	 */
	public String getPrefix(String namespaceURI) {
		return mPrefixByUri.get(namespaceURI);
	}

	/**
	 * <p>Get all prefixes bound to a Namespace URI in the current
	 * scope. (the XML file)</p>
	 * <p>NOTE: Multiple prefixes bound to a similar Namespace URI will be normalized to the first prefix defined.
	 * Still the namespace attributes exist in the XML as inner value prefixes might be used.</p>
	 *
	 * <p><strong>The <code>Iterator</code> is
	 * <em>not</em> modifiable.  e.g. the
	 * <code>remove()</code> method will throw
	 * <code>UnsupportedOperationException</code>.</strong></p>
	 *
	 * <p>When requesting prefixes by Namespace URI, the following
	 * table describes the returned prefixes value for all Namespace
	 * URI values:</p>
	 *
	 * <table border="2" rules="all" cellpadding="4">
	 *   <thead>
	 *     <tr>
	 *       <th align="center" colspan="2"><code>
	 *         getPrefixes(namespaceURI)</code> return value for
	 *         specified Namespace URIs</th>
	 *     </tr>
	 *     <tr>
	 *       <th>Namespace URI parameter</th>
	 *       <th>prefixes value returned</th>
	 *     </tr>
	 *   </thead>
	 *   <tbody>
	 *     <tr>
	 *       <td>bound Namespace URI,
	 *         including the &lt;default Namespace URI&gt;</td>
	 *       <td>
	 *         <code>Iterator</code> over prefixes bound to Namespace URI in
	 *         the current scope in an arbitrary,
	 *         <strong>implementation dependent</strong>,
	 *         order
	 *       </td>
	 *     </tr>
	 *     <tr>
	 *       <td>unbound Namespace URI</td>
	 *       <td>empty <code>Iterator</code></td>
	 *     </tr>
	 *     <tr>
	 *       <td><code>XMLConstants.XML_NS_URI</code>
	 *           ("http://www.w3.org/XML/1998/namespace")</td>
	 *       <td><code>Iterator</code> with one element set to
	 *         <code>XMLConstants.XML_NS_PREFIX</code> ("xml")</td>
	 *     </tr>
	 *     <tr>
	 *       <td><code>XMLConstants.XMLNS_ATTRIBUTE_NS_URI</code>
	 *           ("http://www.w3.org/2000/xmlns/")</td>
	 *       <td><code>Iterator</code> with one element set to
	 *         <code>XMLConstants.XMLNS_ATTRIBUTE</code> ("xmlns")</td>
	 *     </tr>
	 *     <tr>
	 *       <td><code>null</code></td>
	 *       <td><code>IllegalArgumentException</code> is thrown</td>
	 *     </tr>
	 *   </tbody>
	 * </table>
	 *
	 * @param namespaceURI URI of Namespace to lookup
	 *
	 * @return <code>Iterator</code> for all prefixes bound to the
	 *   Namespace URI in the current scope
	 *
	 * @throws IllegalArgumentException When <code>namespaceURI</code> is
	 *   <code>null</code>
	 */
	public Iterator<String> getPrefixes(String namespaceURI) {
		Set<String> prefixes = mDuplicatePrefixesByUri.get(namespaceURI);
		if (prefixes == null) {
			prefixes = new HashSet<String>();
		}
		String givenPrefix = mPrefixByUri.get(namespaceURI);
		if(givenPrefix != null){
			prefixes.add(givenPrefix);
		}
		return prefixes.iterator();
	}

	/** @return a map of namespaces, where the URI is the key and the prefix is the value */
	Map<String, String> getMapNamespacePrefixByUri() {
		return mPrefixByUri;
	}

	/** Adds a new Namespace to the DOM. Making the prefix usable with JDK <code>XPath</code>.
	 * All namespace attributes will be written to the root element during later serialization of the DOM by the <code>OdfPackage</code>.
	 * @param prefix of the namespace to be set to this DOM
	 * @param uri of the namespace to be set to this DOM
	 * @return the namespace that was set. If an URI was registered before to the DOM, the previous prefix will be taken.
	 * In case of a given prefix that was already registered, but related to a new URI, the prefix will be adapted.
	 * The new prefix receives the suffix '__' plus integer, e.g. "__1" for the first duplicate and "__2" for the second.
	 */
	public OdfNamespace setNamespace(String prefix, String uri) {
		//collision detection, when a new prefix/URI pair exists
		OdfNamespace newNamespace = null;
		//Scenario a) the URI already registered, use existing prefix
		// but save all others for the getPrefixes function. There might be still some
		// in attribute values using prefixes, that were not exchanged.
		String existingPrefix = mPrefixByUri.get(uri);
		if (existingPrefix != null) {
			//Use the existing prefix of the used URL, neglect the given
			newNamespace = OdfNamespace.newNamespace(existingPrefix, uri);

			//Add the new prefix to the duplicate prefix map for getPrefixes(String uri)
			Set<String> prefixes = mDuplicatePrefixesByUri.get(uri);
			if (prefixes == null) {
				prefixes = new HashSet<String>();
				mDuplicatePrefixesByUri.put(uri, prefixes);
			}
			prefixes.add(prefix);
		} else {
			//Scenario b) the prefix already exists and the URI does not exist
			String existingURI = mUriByPrefix.get(prefix);
			if (existingURI != null && !existingURI.equals(uri)) {
				//Change the prefix appending "__" plus counter.
				int i = 1;
				do {
					int suffixStart = prefix.lastIndexOf("__");
					if (suffixStart != -1) {
						prefix = prefix.substring(0, suffixStart);
					}
					//users have to take care for their attribute values using namespace prefixes.
					prefix = prefix + "__" + i;
					i++;
					existingURI = mUriByPrefix.get(prefix);
				} while (existingURI != null && !existingURI.equals(uri));
			}
			newNamespace = OdfNamespace.newNamespace(prefix, uri);
			mPrefixByUri.put(uri, prefix);
			mUriByPrefix.put(prefix, uri);
		}
		// if the file Dom is already associated to parsed XML add the new namespace to the root element
		Element root = getRootElement();
		if (root != null) {
			root.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:" + prefix, uri);
		}
		return newNamespace;
	}

	/** Adds a new Namespace to the DOM. Making the prefix usable with JDK <code>XPath</code>.
	 * All namespace attributes will be written to the root element during later serialization of the DOM by the <code>OdfPackage</code>.
	 * @param name the namespace to be set
	 * @return the namespace that was set. If an URI was registered before to the DOM, the previous prefix will be taken.
	 * In case of a given prefix that was already registered, but related to a new URI, the prefix will be adapted.
	 * The new prefix receives the suffix '__' plus integer, e.g. "__1" for the first duplicate and "__2" for the second.
	 */
	public OdfNamespace setNamespace(NamespaceName name) {
		return setNamespace(name.getPrefix(), name.getUri());
	}


	/**
	* Get in-content metadata cache model
	*
	* @return in-content metadata cache model
	*/
	public Map<Node, Model> getInContentMetadataCache() {
		return this.inCententMetadataCache;
	}

	/**
	* Update the in content metadata of the node. It should be called whenever
	* the xhtml:xxx attrbutes values of the node are changed.
	* @param the node, whose in content metadata will be updated
	*/
	public void updateInContentMetadataCache(Node node) {
		this.getInContentMetadataCache().remove(node);
		DOMRDFaParser parser = DOMRDFaParser.createInstance(this.sink);
		String baseUri = Util.getRDFBaseUri(mPackage.getBaseURI(), mPackagePath);
		parser.setBase(baseUri);
		parser.parse(node);
	}

	/**
	* @return the RDF metadata of all the bookmarks within the dom
	*/
	public Model getBookmarkRDFMetadata() {
		return BookmarkRDFMetadataExtractor.newBookmarkTextExtractor().getBookmarkRDFMetadata(this);
	}

	/**
	* The end users needn't to care of this method, which is used by
	* BookmarkRDFMetadataExtractor
	* @return the JenaSink
	*/
	public JenaSink getSink() {
		return sink;
	}
}
