blob: e2fc66e2de31d69da8503fe9e8c01da993bf08d0 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) and others.
* 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:
* Soyatec - initial API and implementation
*******************************************************************************/
package org.eclipse.xwt.tools.ui.designer.editor.model;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.runtime.Assert;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.util.EMap;
import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.eclipse.xwt.tools.ui.xaml.XamlDocument;
import org.eclipse.xwt.tools.ui.xaml.XamlNode;
import org.w3c.dom.Attr;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
/**
* @author jliu jin.liu@soyatec.com
*/
public class BuilderContext {
private static final String CHARACTERS = "abcdefghigklmnopqrstuvwxyz";
private final Map<XamlNode, IDOMNode> model2text = new HashMap<XamlNode, IDOMNode>(
1);
private final Map<IDOMNode, XamlNode> text2model = new HashMap<IDOMNode, XamlNode>(
1);
private XWTModelBuilder modelBuilder;
private IDOMDocument textRoot;
private XamlDocument modelRoot;
private Synchronizer synchronizer;
private Adapter modelAdapter;
private INodeAdapter nodeAdapter;
public BuilderContext(XWTModelBuilder modelBuilder,
IDOMDocument textDocument, XamlDocument modelDocument,
Synchronizer synchronizer) {
Assert.isNotNull(textDocument);
Assert.isNotNull(modelDocument);
this.modelBuilder = modelBuilder;
this.textRoot = textDocument;
this.modelRoot = modelDocument;
this.synchronizer = synchronizer;
}
public XWTModelBuilder getModelBuilder() {
return modelBuilder;
}
public IDOMDocument getTextRoot() {
return textRoot;
}
public XamlDocument getModelRoot() {
return modelRoot;
}
public Synchronizer getSynchronizer() {
if (synchronizer == null) {
synchronizer = new Synchronizer();
}
return synchronizer;
}
public void map(XamlNode model, IDOMNode textNode) {
model2text.put(model, textNode);
text2model.put(textNode, model);
if (model != null && modelAdapter != null
&& !model.eAdapters().contains(modelAdapter)) {
model.eAdapters().add(modelAdapter);
}
if (textNode != null && nodeAdapter != null
&& !textNode.getAdapters().contains(nodeAdapter)) {
textNode.addAdapter(nodeAdapter);
}
}
public void remove(Object obj) {
IDOMNode removedText = model2text.remove(obj);
if (removedText != null) {
text2model.remove(removedText);
if (nodeAdapter != null) {
removedText.removeAdapter(nodeAdapter);
}
}
XamlNode removedModel = text2model.remove(obj);
if (removedModel != null) {
model2text.remove(removedModel);
if (modelAdapter != null) {
removedModel.eAdapters().remove(modelAdapter);
}
}
}
public void clear() {
model2text.clear();
text2model.clear();
}
public XamlNode getModel(Object textNode) {
return text2model.get(textNode);
}
public IDOMNode getTextNode(Object model) {
return model2text.get(model);
}
public List<IDOMElement> getChildNodes(IDOMNode parent) {
if (parent == null) {
return Collections.emptyList();
}
List<IDOMElement> childNodes = new ArrayList<IDOMElement>();
Node child = parent.getFirstChild();
while (child != null) {
if (child instanceof IDOMElement
&& child.getLocalName().indexOf(".") == -1) {
childNodes.add((IDOMElement) child);
}
child = child.getNextSibling();
}
return childNodes;
}
public List<Text> getContentNodes(IDOMNode node) {
NodeList childNodes = node.getChildNodes();
int length = childNodes.getLength();
if (length == 0) {
return Collections.emptyList();
}
List<Text> contentTexts = new ArrayList<Text>();
for (int i = 0; i < length; i++) {
Node item = childNodes.item(i);
if (item.getNodeType() == Node.TEXT_NODE) {
contentTexts.add((Text) item);
}
}
return contentTexts;
}
/**
* Return content of a Node, "<j:String>hello world</j:String>"
*/
public String getContent(IDOMNode parent) {
List<Text> textNodes = getContentNodes(parent);
if (textNodes.isEmpty()) {
return null;
}
StringBuilder content = new StringBuilder();
for (Text text : textNodes) {
String value = text.getNodeValue();
if (value == null) {
continue;
}
value = filter(value.trim());
if (value.length() != 0) {
content.append(value);
}
}
return content.length() > 0 ? content.toString() : null;
}
public String filter(String value) {
value = value.replace("\n", "");
value = value.replace("\t", "");
value = value.replace("\r", "");
return value;
}
public List<IDOMNode> getAttributes(IDOMNode parent) {
if (parent == null) {
return Collections.emptyList();
}
List<IDOMNode> attributes = new ArrayList<IDOMNode>();
NamedNodeMap attrMap = parent.getAttributes();
if (attrMap != null) {
int length = attrMap.getLength();
for (int i = 0; i < length; i++) {
IDOMAttr item = (IDOMAttr) attrMap.item(i);
String name = item.getLocalName();
String prefix = item.getPrefix();
if (name.indexOf(".") != -1) {
name = name.substring(name.indexOf(".") + 1);
prefix = null;
}
if ("xmlns".equals(name)) {
continue;
}
if ("xmlns".equals(prefix)) {
continue;
}
attributes.add(item);
}
}
NodeList children = parent.getChildNodes();
if (children != null) {
for (int i = 0; i < children.getLength(); i++) {
Node item = children.item(i);
String localName = item.getLocalName();
if (item instanceof IDOMElement && localName.indexOf(".") != -1) {
attributes.add((IDOMElement) item);
}
}
}
return attributes;
}
public boolean contains(Node parent, Attr attr) {
NamedNodeMap attributes = parent.getAttributes();
for (int i = attributes.getLength() - 1; i >= 0; i--) {
if (attr == attributes.item(i)) {
return true;
}
}
return false;
}
protected String getPrefix(String namespace) {
EMap<String, String> declaredNamespaces = modelRoot
.getDeclaredNamespaces();
Set<String> existings = declaredNamespaces.keySet();
for (String p : existings) {
if (namespace.equals(declaredNamespaces.get(p))) {
return p;
}
}
char[] c = CHARACTERS.toCharArray();
for (char d : c) {
String prefix = Character.toString(d);
if (!existings.contains(prefix)) {
return prefix;
}
}
return "j";
}
/**
* @param modelAdapter
* the modelAdapter to set
*/
public void setModelAdapter(Adapter modelAdapter) {
this.modelAdapter = modelAdapter;
}
/**
* @return the modelAdapter
*/
public Adapter getModelAdapter() {
return modelAdapter;
}
/**
* @param nodeAdapter
* the nodeAdapter to set
*/
public void setNodeAdapter(INodeAdapter nodeAdapter) {
this.nodeAdapter = nodeAdapter;
}
/**
* @return the nodeAdapter
*/
public INodeAdapter getNodeAdapter() {
return nodeAdapter;
}
}