/******************************************************************************* * Copyright (c) 2000, 2004 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package net.sourceforge.phpdt.internal.corext.template.php; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.MissingResourceException; import java.util.ResourceBundle; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.text.templates.ContextTypeRegistry; import org.eclipse.jface.text.templates.Template; import org.eclipse.jface.text.templates.TemplateContextType; import org.eclipse.jface.text.templates.TemplateException; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.Text; import org.xml.sax.InputSource; import org.xml.sax.SAXException; /** * TemplateSet manages a collection of templates and makes them * persistent. * * @deprecated use TemplateStore instead * @since 3.0 */ public class TemplateSet { private static final String NAME_ATTRIBUTE = "name"; //$NON-NLS-1$ private static final String DESCRIPTION_ATTRIBUTE = "description"; //$NON-NLS-1$ private static final String CONTEXT_ATTRIBUTE = "context"; //$NON-NLS-1$ private List fTemplates = new ArrayList(); private String fTemplateTag; private static final int TEMPLATE_PARSE_EXCEPTION = 10002; private static final int TEMPLATE_IO_EXCEPTION = 10005; private ContextTypeRegistry fRegistry; public TemplateSet(String templateTag, ContextTypeRegistry registry) { fTemplateTag = templateTag; fRegistry = registry; } /** * Convenience method for reading templates from a file. * * @param file * @param allowDuplicates * @param bundle * @see #addFromStream(InputStream, boolean, boolean, ResourceBundle) * @throws CoreException */ public void addFromFile(File file, boolean allowDuplicates, ResourceBundle bundle) throws CoreException { InputStream stream = null; try { stream = new FileInputStream(file); addFromStream(stream, allowDuplicates, false, bundle); } catch (IOException e) { throwReadException(e); } finally { try { if (stream != null) stream.close(); } catch (IOException e) { } } } public String getTemplateTag() { return fTemplateTag; } /** * Reads templates from a XML stream and adds them to the templates * * @param stream * @param allowDuplicates * @param bundle * @param doTranslations * @see #addFromStream(InputStream, boolean, boolean, ResourceBundle) * @throws CoreException */ public void addFromStream(InputStream stream, boolean allowDuplicates, boolean doTranslations, ResourceBundle bundle) throws CoreException { try { DocumentBuilderFactory factory = DocumentBuilderFactory .newInstance(); DocumentBuilder parser = factory.newDocumentBuilder(); Document document = parser.parse(new InputSource(stream)); NodeList elements = document.getElementsByTagName(getTemplateTag()); int count = elements.getLength(); for (int i = 0; i != count; i++) { Node node = elements.item(i); NamedNodeMap attributes = node.getAttributes(); if (attributes == null) continue; String name = getAttributeValue(attributes, NAME_ATTRIBUTE); String description = getAttributeValue(attributes, DESCRIPTION_ATTRIBUTE); if (name == null || description == null) continue; if (doTranslations) { description = translateString(description, bundle); } String context = getAttributeValue(attributes, CONTEXT_ATTRIBUTE); if (name == null || description == null || context == null) throw new SAXException(JavaTemplateMessages .getString("TemplateSet.error.missing.attribute")); //$NON-NLS-1$ StringBuffer buffer = new StringBuffer(); NodeList children = node.getChildNodes(); for (int j = 0; j != children.getLength(); j++) { String value = children.item(j).getNodeValue(); if (value != null) buffer.append(value); } String pattern = buffer.toString().trim(); if (doTranslations) { pattern = translateString(pattern, bundle); } Template template = new Template(name, description, context, pattern); String message = validateTemplate(template); if (message == null) { if (!allowDuplicates) { Template[] templates = getTemplates(name); for (int k = 0; k < templates.length; k++) { remove(templates[k]); } } add(template); } else { throwReadException(null); } } } catch (ParserConfigurationException e) { throwReadException(e); } catch (IOException e) { throwReadException(e); } catch (SAXException e) { throwReadException(e); } } private String translateString(String str, ResourceBundle bundle) { int idx = str.indexOf('%'); if (idx == -1) { return str; } StringBuffer buf = new StringBuffer(); int k = 0; while (idx != -1) { buf.append(str.substring(k, idx)); for (k = idx + 1; k < str.length() && !Character.isWhitespace(str.charAt(k)); k++) { // loop } String key = str.substring(idx + 1, k); buf.append(getBundleString(key, bundle)); idx = str.indexOf('%', k); } buf.append(str.substring(k)); return buf.toString(); } private String getBundleString(String key, ResourceBundle bundle) { if (bundle != null) { try { return bundle.getString(key); } catch (MissingResourceException e) { return '!' + key + '!'; } } else return JavaTemplateMessages.getString(key); // default messages } protected String validateTemplate(Template template) { TemplateContextType type = fRegistry.getContextType(template .getContextTypeId()); if (type == null) { return "Unknown context type: " + template.getContextTypeId(); //$NON-NLS-1$ } try { type.validate(template.getPattern()); return null; } catch (TemplateException e) { return e.getMessage(); } } private String getAttributeValue(NamedNodeMap attributes, String name) { Node node = attributes.getNamedItem(name); return node == null ? null : node.getNodeValue(); } /** * Convenience method for saving to a file. * * @see #saveToStream(OutputStream) */ public void saveToFile(File file) throws CoreException { OutputStream stream = null; try { stream = new FileOutputStream(file); saveToStream(stream); } catch (IOException e) { throwWriteException(e); } finally { try { if (stream != null) stream.close(); } catch (IOException e) { } } } /** * Saves the template set as XML. */ public void saveToStream(OutputStream stream) throws CoreException { try { DocumentBuilderFactory factory = DocumentBuilderFactory .newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.newDocument(); Node root = document.createElement("templates"); //$NON-NLS-1$ document.appendChild(root); for (int i = 0; i != fTemplates.size(); i++) { Template template = (Template) fTemplates.get(i); Node node = document.createElement(getTemplateTag()); root.appendChild(node); NamedNodeMap attributes = node.getAttributes(); Attr name = document.createAttribute(NAME_ATTRIBUTE); name.setValue(template.getName()); attributes.setNamedItem(name); Attr description = document .createAttribute(DESCRIPTION_ATTRIBUTE); description.setValue(template.getDescription()); attributes.setNamedItem(description); Attr context = document.createAttribute(CONTEXT_ATTRIBUTE); context.setValue(template.getContextTypeId()); attributes.setNamedItem(context); Text pattern = document.createTextNode(template.getPattern()); node.appendChild(pattern); } Transformer transformer = TransformerFactory.newInstance() .newTransformer(); transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$ transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$ DOMSource source = new DOMSource(document); StreamResult result = new StreamResult(stream); transformer.transform(source, result); } catch (ParserConfigurationException e) { throwWriteException(e); } catch (TransformerException e) { throwWriteException(e); } } private static void throwReadException(Throwable t) throws CoreException { int code; if (t instanceof SAXException) code = TEMPLATE_PARSE_EXCEPTION; else code = TEMPLATE_IO_EXCEPTION; // IStatus status= JavaUIStatus.createError(code, // TemplateMessages.getString("TemplateSet.error.read"), t); // //$NON-NLS-1$ // throw new JavaUIException(status); throw new CoreException( new Status( IStatus.ERROR, "org.eclipse.jface.text", code, JavaTemplateMessages.getString("TemplateSet.error.read"), t)); //$NON-NLS-1$ //$NON-NLS-2$ } private static void throwWriteException(Throwable t) throws CoreException { // IStatus status= // JavaUIStatus.createError(IJavaStatusConstants.TEMPLATE_IO_EXCEPTION, // TemplateMessages.getString("TemplateSet.error.write"), t); // //$NON-NLS-1$ // throw new JavaUIException(status); throw new CoreException( new Status( IStatus.ERROR, "org.eclipse.jface.text", TEMPLATE_IO_EXCEPTION, JavaTemplateMessages.getString("TemplateSet.error.write"), t)); //$NON-NLS-1$ //$NON-NLS-2$ } /** * Adds a template to the set. */ public void add(Template template) { if (exists(template)) return; // ignore duplicate fTemplates.add(template); } private boolean exists(Template template) { for (Iterator iterator = fTemplates.iterator(); iterator.hasNext();) { Template anotherTemplate = (Template) iterator.next(); if (template.equals(anotherTemplate)) return true; } return false; } /** * Removes a template to the set. */ public void remove(Template template) { fTemplates.remove(template); } /** * Empties the set. */ public void clear() { fTemplates.clear(); } /** * Returns all templates. */ // public Template[] getTemplates() { // return (Template[]) fTemplates.toArray(new Template[fTemplates.size()]); // } /** * Returns all templates with a given name. */ public Template[] getTemplates(String name) { ArrayList res = new ArrayList(); for (Iterator iterator = fTemplates.iterator(); iterator.hasNext();) { Template curr = (Template) iterator.next(); if (curr.getName().equals(name)) { res.add(curr); } } return (Template[]) res.toArray(new Template[res.size()]); } /** * Returns the first templates with the given name. */ // public Template getFirstTemplate(String name) { // for (Iterator iterator = fTemplates.iterator(); iterator.hasNext();) { // Template curr = (Template) iterator.next(); // if (curr.getName().equals(name)) { // return curr; // } // } // return null; // } }