d7de172b989154e82b1fa736dfdc905cddafaf0b
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / corext / template / TemplateSet.java
1 /*
2  * (c) Copyright IBM Corp. 2000, 2001.
3  * All Rights Reserved.
4  */
5 package net.sourceforge.phpdt.internal.corext.template;
6
7 import java.io.File;
8 import java.io.FileInputStream;
9 import java.io.FileOutputStream;
10 import java.io.IOException;
11 import java.io.InputStream;
12 import java.io.OutputStream;
13 import java.util.ArrayList;
14 import java.util.Arrays;
15 import java.util.Comparator;
16 import java.util.Iterator;
17 import java.util.List;
18
19 import javax.xml.parsers.DocumentBuilder;
20 import javax.xml.parsers.DocumentBuilderFactory;
21 import javax.xml.parsers.ParserConfigurationException;
22
23 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
24 import org.apache.xml.serialize.OutputFormat;
25 import org.apache.xml.serialize.Serializer;
26 import org.apache.xml.serialize.SerializerFactory;
27 import org.eclipse.core.runtime.CoreException;
28 import org.w3c.dom.Attr;
29 import org.w3c.dom.Document;
30 import org.w3c.dom.NamedNodeMap;
31 import org.w3c.dom.Node;
32 import org.w3c.dom.NodeList;
33 import org.w3c.dom.Text;
34 import org.xml.sax.InputSource;
35 import org.xml.sax.SAXException;
36 //import org.eclipse.jdt.internal.ui.JavaUIStatus;
37 //import org.eclipse.jdt.internal.ui.JavaUIException;
38
39 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
40
41 /**
42  * <code>TemplateSet</code> manages a collection of templates and makes them
43  * persistent.
44  */
45 public class TemplateSet {
46         
47         private static class TemplateComparator implements Comparator {
48                 public int compare(Object arg0, Object arg1) {
49                         if (arg0 == arg1)
50                                 return 0;
51                         
52                         if (arg0 == null)
53                                 return -1;
54                                 
55                         Template template0= (Template) arg0;
56                         Template template1= (Template) arg1;
57                         
58                         return template0.getName().compareTo(template1.getName());
59                 }
60         }
61
62         private static final String TEMPLATE_TAG= "template"; //$NON-NLS-1$
63         private static final String NAME_ATTRIBUTE= "name"; //$NON-NLS-1$
64         private static final String DESCRIPTION_ATTRIBUTE= "description"; //$NON-NLS-1$
65         private static final String CONTEXT_ATTRIBUTE= "context"; //$NON-NLS-1$
66         private static final String ENABLED_ATTRIBUTE= "enabled"; //$NON-NLS-1$
67
68         private List fTemplates= new ArrayList();
69         private Comparator fTemplateComparator= new TemplateComparator();
70         private Template[] fSortedTemplates= new Template[0];
71         
72         /**
73          * Convenience method for reading templates from a file.
74          * 
75          * @see #addFromStream(InputStream)
76          */
77         public void addFromFile(File file) throws CoreException {
78                 InputStream stream= null;
79
80                 try {
81                         stream= new FileInputStream(file);
82                         addFromStream(stream);
83
84                 } catch (IOException e) {
85                         throwReadException(e);
86
87                 } finally {
88                         try {
89                                 if (stream != null)
90                                         stream.close();
91                         } catch (IOException e) {}
92                 }               
93         }
94
95         /**
96          * Reads templates from a XML stream and adds them to the template set.
97          */     
98         public void addFromStream(InputStream stream) throws CoreException {
99                 try {
100                         DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
101                         DocumentBuilder parser= factory.newDocumentBuilder();           
102                         Document document= parser.parse(new InputSource(stream));
103                         NodeList elements= document.getElementsByTagName(TEMPLATE_TAG);
104                         
105                         int count= elements.getLength();
106                         for (int i= 0; i != count; i++) {
107                                 Node node= elements.item(i);                                    
108                                 NamedNodeMap attributes= node.getAttributes();
109
110                                 if (attributes == null)
111                                         continue;
112
113                                 String name= getAttributeValue(attributes, NAME_ATTRIBUTE);
114                                 String description= getAttributeValue(attributes, DESCRIPTION_ATTRIBUTE);
115                                 String context= getAttributeValue(attributes, CONTEXT_ATTRIBUTE);
116                                 Node enabledNode= attributes.getNamedItem(ENABLED_ATTRIBUTE);
117
118                                 if (name == null || description == null || context == null)
119                                         throw new SAXException(TemplateMessages.getString("TemplateSet.error.missing.attribute")); //$NON-NLS-1$
120
121                                 boolean enabled= (enabledNode == null) || (enabledNode.getNodeValue().equals("true")); //$NON-NLS-1$
122
123                                 StringBuffer buffer= new StringBuffer();
124                                 NodeList children= node.getChildNodes();
125                                 for (int j= 0; j != children.getLength(); j++) {
126                                         String value= children.item(j).getNodeValue();
127                                         if (value != null)
128                                                 buffer.append(value);
129                                 }
130                                 String pattern= buffer.toString().trim();
131
132                                 Template template= new Template(name, description, context, pattern);   
133                                 template.setEnabled(enabled);
134                                 add(template);
135                         }
136         
137                         sort();
138
139                 } catch (ParserConfigurationException e) {
140                         throwReadException(e);
141                 } catch (IOException e) {
142                         throwReadException(e);
143                 } catch (SAXException e) {
144                         throwReadException(e);
145                 }
146         }
147         
148         private String getAttributeValue(NamedNodeMap attributes, String name) {
149                 Node node= attributes.getNamedItem(name);
150
151                 return node == null
152                         ? null
153                         : node.getNodeValue();
154         }
155
156         /**
157          * Convenience method for saving to a file.
158          * 
159          * @see #saveToStream(OutputStream)
160          */
161         public void saveToFile(File file) throws CoreException {
162                 OutputStream stream= null;
163
164                 try {
165                         stream= new FileOutputStream(file);
166                         saveToStream(stream);
167
168                 } catch (IOException e) {
169                         throwWriteException(e);
170
171                 } finally {
172                         try {
173                                 if (stream != null)
174                                         stream.close();
175                         } catch (IOException e) {}
176                 }
177         }
178                 
179         /**
180          * Saves the template set as XML.
181          */
182         public void saveToStream(OutputStream stream) throws CoreException {
183                 try {
184                         DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
185                         DocumentBuilder builder= factory.newDocumentBuilder();          
186                         Document document= builder.newDocument();
187
188                         Node root= document.createElement("templates"); // $NON-NLS-1$ //$NON-NLS-1$
189                         document.appendChild(root);
190                         
191                         for (int i= 0; i != fTemplates.size(); i++) {
192                                 Template template= (Template) fTemplates.get(i);
193                                 
194                                 Node node= document.createElement("template"); // $NON-NLS-1$ //$NON-NLS-1$
195                                 root.appendChild(node);
196                                 
197                                 NamedNodeMap attributes= node.getAttributes();
198                                 
199                                 Attr name= document.createAttribute(NAME_ATTRIBUTE);
200                                 name.setValue(template.getName());
201                                 attributes.setNamedItem(name);
202         
203                                 Attr description= document.createAttribute(DESCRIPTION_ATTRIBUTE);
204                                 description.setValue(template.getDescription());
205                                 attributes.setNamedItem(description);
206         
207                                 Attr context= document.createAttribute(CONTEXT_ATTRIBUTE);
208                                 context.setValue(template.getContextTypeName());
209                                 attributes.setNamedItem(context);                       
210
211                                 Attr enabled= document.createAttribute(ENABLED_ATTRIBUTE);
212                                 enabled.setValue(template.isEnabled() ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
213                                 attributes.setNamedItem(enabled);
214                                 
215                                 Text pattern= document.createTextNode(template.getPattern());
216                                 node.appendChild(pattern);                      
217                         }               
218                         
219                         OutputFormat format = new OutputFormat();
220                         format.setPreserveSpace(true);
221                         Serializer serializer = SerializerFactory.getSerializerFactory("xml").makeSerializer(stream, format); //$NON-NLS-1$
222                         serializer.asDOMSerializer().serialize(document);
223
224                 } catch (ParserConfigurationException e) {
225                         throwWriteException(e);
226                 } catch (IOException e) {
227                         throwWriteException(e);
228                 }               
229         }
230
231         private static void throwReadException(Throwable t) throws CoreException {
232     PHPeclipsePlugin.log(t);
233 //              IStatus status= new JavaUIStatus(JavaStatusConstants.TEMPLATE_IO_EXCEPTION,
234 //                      TemplateMessages.getString("TemplateSet.error.read"), t); //$NON-NLS-1$
235 //              throw new JavaUIException(status);
236         }
237         
238         private static void throwWriteException(Throwable t) throws CoreException {
239     PHPeclipsePlugin.log(t);
240 //              IStatus status= new JavaUIStatus(JavaStatusConstants.TEMPLATE_IO_EXCEPTION,
241 //                      TemplateMessages.getString("TemplateSet.error.write"), t); //$NON-NLS-1$
242 //              throw new JavaUIException(status);
243         }
244
245         /**
246          * Adds a template to the set.
247          */
248         public void add(Template template) {
249                 if (exists(template))
250                         return; // ignore duplicate
251                 
252                 fTemplates.add(template);
253                 sort();
254         }
255
256         private boolean exists(Template template) {
257                 for (Iterator iterator = fTemplates.iterator(); iterator.hasNext();) {
258                         Template anotherTemplate = (Template) iterator.next();
259
260                         if (template.equals(anotherTemplate))
261                                 return true;
262                 }
263                 
264                 return false;
265         }
266         
267         /**
268          * Removes a template to the set.
269          */     
270         public void remove(Template template) {
271                 fTemplates.remove(template);
272                 sort();
273         }
274
275         /**
276          * Empties the set.
277          */             
278         public void clear() {
279                 fTemplates.clear();
280                 sort();
281         }
282         
283         /**
284          * Returns all templates.
285          */
286         public Template[] getTemplates() {
287                 return (Template[]) fTemplates.toArray(new Template[fTemplates.size()]);
288         }
289         
290         /**
291          * Returns all templates with a given name.
292          */
293         public Template[] getTemplates(String name) {
294                 ArrayList res= new ArrayList();
295                 for (Iterator iterator= fTemplates.iterator(); iterator.hasNext();) {
296                         Template curr= (Template) iterator.next();
297                         if (curr.getName().equals(name)) {
298                                 res.add(curr);
299                         }
300                 }
301                 return (Template[]) res.toArray(new Template[res.size()]);
302         }       
303         
304         private void sort() {
305                 fSortedTemplates= (Template[]) fTemplates.toArray(new Template[fTemplates.size()]);
306                 Arrays.sort(fSortedTemplates, fTemplateComparator);
307         }
308         
309 }
310