1 /*******************************************************************************
2 * Copyright (c) 2000, 2011 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.jdt.internal.corext.template.java;
14 import java.io.FileInputStream;
15 import java.io.FileOutputStream;
16 import java.io.IOException;
17 import java.io.InputStream;
18 import java.io.OutputStream;
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.Iterator;
22 import java.util.List;
24 import javax.xml.parsers.DocumentBuilder;
25 import javax.xml.parsers.DocumentBuilderFactory;
26 import javax.xml.parsers.ParserConfigurationException;
27 import javax.xml.transform.OutputKeys;
28 import javax.xml.transform.Transformer;
29 import javax.xml.transform.TransformerException;
30 import javax.xml.transform.TransformerFactory;
31 import javax.xml.transform.dom.DOMSource;
32 import javax.xml.transform.stream.StreamResult;
34 import org.xml.sax.InputSource;
35 import org.xml.sax.SAXException;
36 import org.xml.sax.helpers.DefaultHandler;
38 import org.w3c.dom.Attr;
39 import org.w3c.dom.Document;
40 import org.w3c.dom.NamedNodeMap;
41 import org.w3c.dom.Node;
42 import org.w3c.dom.NodeList;
43 import org.w3c.dom.Text;
45 import org.eclipse.core.runtime.CoreException;
46 import org.eclipse.core.runtime.IStatus;
47 import org.eclipse.core.runtime.Status;
49 import org.eclipse.jface.text.templates.ContextTypeRegistry;
50 import org.eclipse.jface.text.templates.Template;
51 import org.eclipse.jface.text.templates.TemplateContextType;
52 import org.eclipse.jface.text.templates.TemplateException;
53 import org.eclipse.jface.text.templates.persistence.TemplatePersistenceData;
55 import org.eclipse.jdt.internal.ui.CompatibilityTemplateStore;
58 * <code>TemplateSet</code> manages a collection of templates and makes them
61 * @deprecated use TemplateStore instead
64 public class TemplateSet {
66 private static final String NAME_ATTRIBUTE= "name"; //$NON-NLS-1$
67 private static final String DESCRIPTION_ATTRIBUTE= "description"; //$NON-NLS-1$
68 private static final String CONTEXT_ATTRIBUTE= "context"; //$NON-NLS-1$
70 private List<Template> fTemplates= new ArrayList<Template>();
71 private String fTemplateTag;
73 private static final int TEMPLATE_PARSE_EXCEPTION= 10002;
74 private static final int TEMPLATE_IO_EXCEPTION= 10005;
75 private ContextTypeRegistry fRegistry;
77 public TemplateSet(String templateTag, ContextTypeRegistry registry) {
78 fTemplateTag= templateTag;
83 * Convenience method for reading templates from a file.
85 * @param file the file
86 * @param allowDuplicates <code>true</code> if duplicates are allowed
87 * @throws CoreException if reading fails
88 * @see #addFromStream(InputStream, boolean)
90 public void addFromFile(File file, boolean allowDuplicates) throws CoreException {
91 InputStream stream= null;
94 stream= new FileInputStream(file);
95 addFromStream(stream, allowDuplicates);
97 } catch (IOException e) {
98 throwReadException(e);
104 } catch (IOException e) {
110 public String getTemplateTag() {
116 * Reads templates from a XML stream and adds them to the templates
118 * @param stream the input stream
119 * @param allowDuplicates <code>true</code> if duplicates are allowed
120 * @throws CoreException if reading fails
122 public void addFromStream(InputStream stream, boolean allowDuplicates) throws CoreException {
124 DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
125 DocumentBuilder parser= factory.newDocumentBuilder();
126 parser.setErrorHandler(new DefaultHandler());
127 Document document= parser.parse(new InputSource(stream));
129 NodeList elements= document.getElementsByTagName(getTemplateTag());
131 int count= elements.getLength();
132 for (int i= 0; i != count; i++) {
133 Node node= elements.item(i);
134 NamedNodeMap attributes= node.getAttributes();
136 if (attributes == null)
139 String name= getAttributeValue(attributes, NAME_ATTRIBUTE);
140 String description= getAttributeValue(attributes, DESCRIPTION_ATTRIBUTE);
141 if (name == null || description == null)
144 String context= getAttributeValue(attributes, CONTEXT_ATTRIBUTE);
147 throw new SAXException(JavaTemplateMessages.TemplateSet_error_missing_attribute);
149 StringBuffer buffer= new StringBuffer();
150 NodeList children= node.getChildNodes();
151 for (int j= 0; j != children.getLength(); j++) {
152 String value= children.item(j).getNodeValue();
154 buffer.append(value);
156 String pattern= buffer.toString().trim();
158 Template template= new Template(name, description, context, pattern, true);
160 String message= validateTemplate(template);
161 if (message == null) {
162 if (!allowDuplicates) {
163 Template[] templates= getTemplates(name);
164 for (int k= 0; k < templates.length; k++) {
165 remove(templates[k]);
170 throwReadException(null);
173 } catch (ParserConfigurationException e) {
174 throwReadException(e);
175 } catch (IOException e) {
176 throwReadException(e);
177 } catch (SAXException e) {
178 throwReadException(e);
182 protected String validateTemplate(Template template) {
183 TemplateContextType type= fRegistry.getContextType(template.getContextTypeId());
185 return "Unknown context type: " + template.getContextTypeId(); //$NON-NLS-1$
188 type.validate(template.getPattern());
190 } catch (TemplateException e) {
191 return e.getMessage();
195 private String getAttributeValue(NamedNodeMap attributes, String name) {
196 Node node= attributes.getNamedItem(name);
200 : node.getNodeValue();
204 * Convenience method for saving to a file.
206 * @param file the file
207 * @throws CoreException in case the save operation fails
208 * @see #saveToStream(OutputStream)
210 public void saveToFile(File file) throws CoreException {
211 OutputStream stream= null;
214 stream= new FileOutputStream(file);
215 saveToStream(stream);
217 } catch (IOException e) {
218 throwWriteException(e);
224 } catch (IOException e) {
231 * Saves the template set as XML.
233 * @param stream the stream
234 * @throws CoreException in case the save operation fails
236 public void saveToStream(OutputStream stream) throws CoreException {
238 DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
239 DocumentBuilder builder= factory.newDocumentBuilder();
240 Document document= builder.newDocument();
242 Node root= document.createElement("templates"); //$NON-NLS-1$
243 document.appendChild(root);
245 for (int i= 0; i != fTemplates.size(); i++) {
246 Template template= fTemplates.get(i);
248 Node node= document.createElement(getTemplateTag());
249 root.appendChild(node);
251 NamedNodeMap attributes= node.getAttributes();
253 Attr name= document.createAttribute(NAME_ATTRIBUTE);
254 name.setValue(template.getName());
255 attributes.setNamedItem(name);
257 Attr description= document.createAttribute(DESCRIPTION_ATTRIBUTE);
258 description.setValue(template.getDescription());
259 attributes.setNamedItem(description);
261 Attr context= document.createAttribute(CONTEXT_ATTRIBUTE);
262 context.setValue(template.getContextTypeId());
263 attributes.setNamedItem(context);
265 Text pattern= document.createTextNode(template.getPattern());
266 node.appendChild(pattern);
270 Transformer transformer=TransformerFactory.newInstance().newTransformer();
271 transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
272 transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
273 DOMSource source = new DOMSource(document);
274 StreamResult result = new StreamResult(stream);
276 transformer.transform(source, result);
278 } catch (ParserConfigurationException e) {
279 throwWriteException(e);
280 } catch (TransformerException e) {
281 throwWriteException(e);
285 private static void throwReadException(Throwable t) throws CoreException {
287 if (t instanceof SAXException)
288 code= TEMPLATE_PARSE_EXCEPTION;
290 code= TEMPLATE_IO_EXCEPTION;
291 // IStatus status= JavaUIStatus.createError(code, TemplateMessages.getString("TemplateSet.error.read"), t); //$NON-NLS-1$
292 // throw new JavaUIException(status);
293 throw new CoreException(new Status(IStatus.ERROR, "org.eclipse.jface.text", code, JavaTemplateMessages.TemplateSet_error_read, t)); //$NON-NLS-1$
296 private static void throwWriteException(Throwable t) throws CoreException {
297 // IStatus status= JavaUIStatus.createError(IJavaStatusConstants.TEMPLATE_IO_EXCEPTION,
298 // TemplateMessages.getString("TemplateSet.error.write"), t); //$NON-NLS-1$
299 // throw new JavaUIException(status);
300 throw new CoreException(new Status(IStatus.ERROR, "org.eclipse.jface.text", TEMPLATE_IO_EXCEPTION, JavaTemplateMessages.TemplateSet_error_write, t)); //$NON-NLS-1$
304 * Adds a template to the set.
306 * @param template the template to add to the set
308 public void add(Template template) {
309 if (exists(template))
310 return; // ignore duplicate
312 fTemplates.add(template);
315 private boolean exists(Template template) {
316 for (Iterator<Template> iterator = fTemplates.iterator(); iterator.hasNext();) {
317 Template anotherTemplate = iterator.next();
319 if (template.equals(anotherTemplate))
327 * Removes a template to the set.
329 * @param template the template to remove from the set
331 public void remove(Template template) {
332 fTemplates.remove(template);
338 public void clear() {
343 * Returns all templates.
345 * @return all templates
347 public Template[] getTemplates() {
348 return fTemplates.toArray(new Template[fTemplates.size()]);
352 * Returns all templates with a given name.
354 * @param name the template name
355 * @return the templates with the given name
357 public Template[] getTemplates(String name) {
358 ArrayList<Template> res= new ArrayList<Template>();
359 for (Iterator<Template> iterator= fTemplates.iterator(); iterator.hasNext();) {
360 Template curr= iterator.next();
361 if (curr.getName().equals(name)) {
365 return res.toArray(new Template[res.size()]);
369 * Returns the first templates with the given name.
371 * @param name the template name
372 * @return the first template with the given name
374 public Template getFirstTemplate(String name) {
375 for (Iterator<Template> iterator= fTemplates.iterator(); iterator.hasNext();) {
376 Template curr= iterator.next();
377 if (curr.getName().equals(name)) {
384 public void generated_1607121912083686967(CompatibilityTemplateStore compatibilitytemplatestore) {
385 List<Template> legacyTemplates= new ArrayList<Template>(Arrays.asList(getTemplates()));
388 TemplatePersistenceData[] datas= compatibilitytemplatestore.getTemplateData(true);
389 for (Iterator<Template> it= legacyTemplates.listIterator(); it.hasNext();) {
390 Template t= it.next();
391 TemplatePersistenceData orig= CompatibilityTemplateStore.findSimilarTemplate(datas, t, compatibilitytemplatestore.isCodeTemplates());
392 if (orig == null) { // no contributed match for the old template found
393 if (!compatibilitytemplatestore.isCodeTemplates())
394 compatibilitytemplatestore.add(new TemplatePersistenceData(t, true));
395 } else { // a contributed template seems to be the descendant of the non-id template t
396 if (!orig.getTemplate().getPattern().equals(t.getPattern()))
397 // add as modified contributed template if changed compared to the original