blob: 83ebf27a4a7b712ae6264db4336c6c52cc93a0be [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006 Sybase, Inc. 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:
* Sybase, Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.jst.pagedesigner.editors.palette.impl;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.eclipse.jst.jsf.common.ui.internal.logging.Logger;
import org.eclipse.jst.pagedesigner.PDPlugin;
import org.eclipse.jst.pagedesigner.editors.palette.MetadataTagDropSourceData;
import org.eclipse.jst.pagedesigner.utils.JSPUtil;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.SAXException;
/**
*
* @author mengbo
*/
public class PaletteElementTemplateHelper {
//private static final String TEMPLATE_ITEM_NAME = "template";
private static final String PREFIX_ATTRIBUTE = "_uri_"; //$NON-NLS-1$
// private static Logger _log = PDPlugin
// .getLogger(PaletteElementTemplateHelper.class);
/**
* This method is used to process template element which is read from .xmi
* file and generate default element.
*
* @param model
* @param element
* @param creationProvider
*/
public static void applyTemplate(IDOMModel model, Element element,
MetadataTagDropSourceData creationProvider) {
if (element == null || element.getLocalName() == null) {
return;
}
Node[] templateNodes = getTemplateNodes(model, creationProvider);
if (templateNodes != null) {
for (int i=0;i<templateNodes.length;i++){
Node anode = templateNodes[i];
element.appendChild(anode);
}
}
}
private static Node[] getTemplateNodes(IDOMModel model,
MetadataTagDropSourceData creationProvider) {
if (creationProvider == null)
return null;
String template = creationProvider.getTemplate();
if (template != null){
final String nodeStr = prepareNode(template);//(String)template.getTemplate();
final Logger logger = PDPlugin.getLogger(PaletteElementTemplateHelper.class);
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
factory.setValidating(false);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new ByteArrayInputStream( nodeStr.getBytes()));
Node beginNode = doc.getFirstChild();
Node templateNode = beginNode.cloneNode(true);//model.getDocument().importNode(beginNode, true);
Node[] templateNodes = applyPrefixes(model, templateNode.getChildNodes(), model.getDocument());
return templateNodes;
} catch (ParserConfigurationException e) {
logger.error(e);
} catch (SAXException e) {
logger.error(e);
} catch (IOException e) {
logger.error(e);
} catch (Exception e){
logger.error(e);
}
}
return null;
}
/**
* @param template
* @return xml as String wrapped by a <begin> node as template may not have a single root element
*/
private static String prepareNode(String template) {
StringBuffer buf = new StringBuffer("<begin>"); //$NON-NLS-1$
buf.append(template);
buf.append("</begin>"); //$NON-NLS-1$
return buf.toString();
}
/**
* Use the actrual prefixs of jsf html and jsf core to set the prefix of
* each node declared in template.
* @param model
* @param templateNodes
* @param document
* @return Node[]
*
*/
public static Node[] applyPrefixes(IDOMModel model,
NodeList templateNodes, Document document) {
List result = new ArrayList();
for (int i = 0, n = templateNodes.getLength(); i < n; i++) {
Node node = cloneNodeDeep(model, document, templateNodes.item(i));
if (node instanceof Element) {
result.add(node);
}
}
return (Node[]) result.toArray(new Node[result.size()]);
}
/**
* TODO: Later we may add some logic to reference the tld file through tag
* name to resolve the prefixs directly.
*/
private static void internalApplyPrefixes(IDOMModel model, Element refNode, Element node) {
if (node != null && refNode != null) {
String uri = refNode.getAttribute(PREFIX_ATTRIBUTE);
if (uri != null) {
String prefix = JSPUtil.getOrCreatePrefix(model, uri, null);
node.setPrefix(prefix);
}
}
}
/**
* A deep clone of the sourceNode
* @param model
* @param destDoc
* @param sourceNode
* @return Node
*/
public static Node cloneNodeDeep(IDOMModel model, Document destDoc, Node sourceNode) {
switch (sourceNode.getNodeType()) {
case Node.ELEMENT_NODE:
Element sourceEle = (Element) sourceNode;
Element resultEle = destDoc.createElement(sourceEle.getTagName());
internalApplyPrefixes(model, sourceEle, resultEle);
NamedNodeMap attrs = sourceEle.getAttributes();
for (int i = 0, size = attrs.getLength(); i < size; i++) {
Attr a = (Attr) attrs.item(i);
if (!PREFIX_ATTRIBUTE.equalsIgnoreCase(a.getNodeName())) {
resultEle.setAttribute(a.getName(), a.getValue());
}
}
NodeList children = sourceEle.getChildNodes();
for (int i = 0, size = children.getLength(); i < size; i++) {
Node n = children.item(i);
Node d = cloneNodeDeep(model, destDoc, n);
if (d != null) {
resultEle.appendChild(d);
}
}
return resultEle;
case Node.TEXT_NODE:
Text txt = destDoc.createTextNode(sourceNode.getNodeValue());
if (txt instanceof IDOMText && sourceNode instanceof IDOMText) {
try {
((IDOMText) txt).setSource(((IDOMText) sourceNode)
.getSource());
} catch (Exception ex) {
// ignore
}
}
return txt;
case Node.CDATA_SECTION_NODE:
return destDoc.createCDATASection(sourceNode.getNodeValue());
default:
return null; // not support.
}
}
}