/*******************************************************************************
* Copyright (c) 2009, 2011 Spring IDE Developers
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Spring IDE Developers - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.beans.core.internal.model.namespaces;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
import org.springframework.util.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
/**
* Utility that manages an internal stack of {@link Document}.
* @author Christian Dupuis
* @since 2.2.7
*/
public class DocumentAccessor {
private Stack<Document> documents = new Stack<Document>();
private Stack<Node> elements = new Stack<Node>();
private Node lastElement = null;
private Document lastDocument = null;
private Map<Document, SchemaLocations> schemaLocations = new HashMap<Document, SchemaLocations>();
/** Push a new document onto the internal stack structure */
public void pushDocument(Document doc) {
lastDocument = doc;
documents.push(doc);
}
/** Push a new element onto the internal stack structure */
public void pushElement(Node element) {
lastElement = element;
elements.push(element);
}
/** Returns the current document; meaning the first document in the stack */
public Document getCurrentDocument() {
if (!documents.isEmpty()) {
return documents.peek();
}
return null;
}
/** Retuns the last procssed document */
public Document getLastDocument() {
return lastDocument;
}
/** Returns the current element; meaning the first element in the stack */
public Node getCurrentElement() {
if (!elements.isEmpty()) {
return elements.peek();
}
return null;
}
/** Returns the last processed element */
public Node getLastElement() {
return lastElement;
}
/** Returns the current values of the schemaLocation attribute */
public synchronized SchemaLocations getCurrentSchemaLocations() {
Document doc = getCurrentDocument();
if (!this.schemaLocations.containsKey(doc)) {
if (doc != null && doc.getDocumentElement() != null) {
SchemaLocations schemaLocations = new SchemaLocations();
schemaLocations.initSchemaLocations(doc.getDocumentElement().getAttributeNS(
"http://www.w3.org/2001/XMLSchema-instance", "schemaLocation"));
this.schemaLocations.put(doc, schemaLocations);
}
}
return this.schemaLocations.get(doc);
}
/** Removes the first document from the stack */
public Document popDocument() {
if (!documents.isEmpty()) {
return documents.pop();
}
return null;
}
/** Removes the first element from the stack */
public Node popElement() {
if (!elements.isEmpty()) {
return elements.pop();
}
return null;
}
/**
* Internal class that parses the value of the <code>schemaLocation</code> attribute and offers accessors to the
* mapping.
*/
static class SchemaLocations {
private Map<String, String> mapping = new HashMap<String, String>();
public void initSchemaLocations(String schemaLocations) {
if (StringUtils.hasLength(schemaLocations)) {
String[] tokens = StringUtils.tokenizeToStringArray(schemaLocations, " \r\n");
if (tokens.length % 2 == 0) {
for (int i = 0; i < tokens.length; i = i + 2) {
mapping.put(tokens[i], tokens[i + 1]);
}
}
}
}
public String getSchemaLocation(String namespaceUri) {
return mapping.get(namespaceUri);
}
}
}