KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jface > text > templates > persistence > TemplateReaderWriter


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jface.text.templates.persistence;
12
13 import java.io.IOException JavaDoc;
14 import java.io.InputStream JavaDoc;
15 import java.io.OutputStream JavaDoc;
16 import java.io.Reader JavaDoc;
17 import java.io.Writer JavaDoc;
18 import java.util.ArrayList JavaDoc;
19 import java.util.Collection JavaDoc;
20 import java.util.HashSet JavaDoc;
21 import java.util.MissingResourceException JavaDoc;
22 import java.util.ResourceBundle JavaDoc;
23 import java.util.Set JavaDoc;
24
25 import javax.xml.parsers.DocumentBuilder JavaDoc;
26 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
27 import javax.xml.parsers.ParserConfigurationException JavaDoc;
28 import javax.xml.transform.OutputKeys JavaDoc;
29 import javax.xml.transform.Transformer JavaDoc;
30 import javax.xml.transform.TransformerException JavaDoc;
31 import javax.xml.transform.TransformerFactory JavaDoc;
32 import javax.xml.transform.dom.DOMSource JavaDoc;
33 import javax.xml.transform.stream.StreamResult JavaDoc;
34
35 import org.w3c.dom.Attr JavaDoc;
36 import org.w3c.dom.Document JavaDoc;
37 import org.w3c.dom.NamedNodeMap JavaDoc;
38 import org.w3c.dom.Node JavaDoc;
39 import org.w3c.dom.NodeList JavaDoc;
40 import org.w3c.dom.Text JavaDoc;
41
42 import org.eclipse.core.runtime.Assert;
43
44 import org.xml.sax.InputSource JavaDoc;
45 import org.xml.sax.SAXException JavaDoc;
46
47 import org.eclipse.jface.text.templates.Template;
48
49 /**
50  * Serializes templates as character or byte stream and reads the same format
51  * back.
52  * <p>
53  * Clients may instantiate this class, it is not intended to be
54  * subclassed.</p>
55  *
56  * @since 3.0
57  */

58 public class TemplateReaderWriter {
59
60     private static final String JavaDoc TEMPLATE_ROOT = "templates"; //$NON-NLS-1$
61
private static final String JavaDoc TEMPLATE_ELEMENT = "template"; //$NON-NLS-1$
62
private static final String JavaDoc NAME_ATTRIBUTE= "name"; //$NON-NLS-1$
63
private static final String JavaDoc ID_ATTRIBUTE= "id"; //$NON-NLS-1$
64
private static final String JavaDoc DESCRIPTION_ATTRIBUTE= "description"; //$NON-NLS-1$
65
private static final String JavaDoc CONTEXT_ATTRIBUTE= "context"; //$NON-NLS-1$
66
private static final String JavaDoc ENABLED_ATTRIBUTE= "enabled"; //$NON-NLS-1$
67
private static final String JavaDoc DELETED_ATTRIBUTE= "deleted"; //$NON-NLS-1$
68
/**
69      * @since 3.1
70      */

71     private static final String JavaDoc AUTO_INSERTABLE_ATTRIBUTE= "autoinsert"; //$NON-NLS-1$
72

73     /**
74      * Create a new instance.
75      */

76     public TemplateReaderWriter() {
77     }
78
79     /**
80      * Reads templates from a reader and returns them. The reader must present
81      * a serialized form as produced by the <code>save</code> method.
82      *
83      * @param reader the reader to read templates from
84      * @return the read templates, encapsulated in instances of <code>TemplatePersistenceData</code>
85      * @throws IOException if reading from the stream fails
86      */

87     public TemplatePersistenceData[] read(Reader JavaDoc reader) throws IOException JavaDoc {
88         return read(reader, null);
89     }
90
91     /**
92      * Reads the template with identifier <code>id</code> from a reader and
93      * returns it. The reader must present a serialized form as produced by the
94      * <code>save</code> method.
95      *
96      * @param reader the reader to read templates from
97      * @param id the id of the template to return
98      * @return the read template, encapsulated in an instances of
99      * <code>TemplatePersistenceData</code>
100      * @throws IOException if reading from the stream fails
101      * @since 3.1
102      */

103     public TemplatePersistenceData readSingle(Reader JavaDoc reader, String JavaDoc id) throws IOException JavaDoc {
104         TemplatePersistenceData[] datas= read(new InputSource JavaDoc(reader), null, id);
105         if (datas.length > 0)
106             return datas[0];
107         return null;
108     }
109
110     /**
111      * Reads templates from a stream and adds them to the templates.
112      *
113      * @param reader the reader to read templates from
114      * @param bundle a resource bundle to use for translating the read templates, or <code>null</code> if no translation should occur
115      * @return the read templates, encapsulated in instances of <code>TemplatePersistenceData</code>
116      * @throws IOException if reading from the stream fails
117      */

118     public TemplatePersistenceData[] read(Reader JavaDoc reader, ResourceBundle JavaDoc bundle) throws IOException JavaDoc {
119         return read(new InputSource JavaDoc(reader), bundle, null);
120     }
121
122     /**
123      * Reads templates from a stream and adds them to the templates.
124      *
125      * @param stream the byte stream to read templates from
126      * @param bundle a resource bundle to use for translating the read templates, or <code>null</code> if no translation should occur
127      * @return the read templates, encapsulated in instances of <code>TemplatePersistenceData</code>
128      * @throws IOException if reading from the stream fails
129      */

130     public TemplatePersistenceData[] read(InputStream JavaDoc stream, ResourceBundle JavaDoc bundle) throws IOException JavaDoc {
131         return read(new InputSource JavaDoc(stream), bundle, null);
132     }
133
134     /**
135      * Reads templates from an <code>InputSource</code> and adds them to the templates.
136      *
137      * @param source the input source
138      * @param bundle a resource bundle to use for translating the read templates, or <code>null</code> if no translation should occur
139      * @param singleId the template id to extract, or <code>null</code> to read in all templates
140      * @return the read templates, encapsulated in instances of <code>TemplatePersistenceData</code>
141      * @throws IOException if reading from the stream fails
142      */

143     private TemplatePersistenceData[] read(InputSource JavaDoc source, ResourceBundle JavaDoc bundle, String JavaDoc singleId) throws IOException JavaDoc {
144         try {
145             Collection JavaDoc templates= new ArrayList JavaDoc();
146             Set JavaDoc ids= new HashSet JavaDoc();
147
148             DocumentBuilderFactory JavaDoc factory= DocumentBuilderFactory.newInstance();
149             DocumentBuilder JavaDoc parser= factory.newDocumentBuilder();
150             Document JavaDoc document= parser.parse(source);
151
152             NodeList JavaDoc elements= document.getElementsByTagName(TEMPLATE_ELEMENT);
153
154             int count= elements.getLength();
155             for (int i= 0; i != count; i++) {
156                 Node JavaDoc node= elements.item(i);
157                 NamedNodeMap JavaDoc attributes= node.getAttributes();
158
159                 if (attributes == null)
160                     continue;
161
162                 String JavaDoc id= getStringValue(attributes, ID_ATTRIBUTE, null);
163                 if (id != null && ids.contains(id))
164                     throw new IOException JavaDoc(TemplatePersistenceMessages.getString("TemplateReaderWriter.duplicate.id")); //$NON-NLS-1$
165

166                 if (singleId != null && !singleId.equals(id))
167                     continue;
168
169                 boolean deleted = getBooleanValue(attributes, DELETED_ATTRIBUTE, false);
170
171                 String JavaDoc name= getStringValue(attributes, NAME_ATTRIBUTE);
172                 name= translateString(name, bundle);
173
174                 String JavaDoc description= getStringValue(attributes, DESCRIPTION_ATTRIBUTE, ""); //$NON-NLS-1$
175
description= translateString(description, bundle);
176
177                 String JavaDoc context= getStringValue(attributes, CONTEXT_ATTRIBUTE);
178
179                 if (name == null || context == null)
180                     throw new IOException JavaDoc(TemplatePersistenceMessages.getString("TemplateReaderWriter.error.missing_attribute")); //$NON-NLS-1$
181

182                 boolean enabled = getBooleanValue(attributes, ENABLED_ATTRIBUTE, true);
183                 boolean autoInsertable= getBooleanValue(attributes, AUTO_INSERTABLE_ATTRIBUTE, true);
184
185                 StringBuffer JavaDoc buffer= new StringBuffer JavaDoc();
186                 NodeList JavaDoc children= node.getChildNodes();
187                 for (int j= 0; j != children.getLength(); j++) {
188                     String JavaDoc value= children.item(j).getNodeValue();
189                     if (value != null)
190                         buffer.append(value);
191                 }
192                 String JavaDoc pattern= buffer.toString();
193                 pattern= translateString(pattern, bundle);
194
195                 Template template= new Template(name, description, context, pattern, autoInsertable);
196                 TemplatePersistenceData data= new TemplatePersistenceData(template, enabled, id);
197                 data.setDeleted(deleted);
198
199                 templates.add(data);
200
201                 if (singleId != null && singleId.equals(id))
202                     break;
203             }
204
205             return (TemplatePersistenceData[]) templates.toArray(new TemplatePersistenceData[templates.size()]);
206
207         } catch (ParserConfigurationException JavaDoc e) {
208             Assert.isTrue(false);
209         } catch (SAXException JavaDoc e) {
210             Throwable JavaDoc t= e.getCause();
211             if (t instanceof IOException JavaDoc)
212                 throw (IOException JavaDoc) t;
213             else if (t != null)
214                 throw new IOException JavaDoc(t.getMessage());
215             else
216                 throw new IOException JavaDoc(e.getMessage());
217         }
218
219         return null; // dummy
220
}
221
222     /**
223      * Saves the templates as XML, encoded as UTF-8 onto the given byte stream.
224      *
225      * @param templates the templates to save
226      * @param stream the byte output to write the templates to in XML
227      * @throws IOException if writing the templates fails
228      */

229     public void save(TemplatePersistenceData[] templates, OutputStream JavaDoc stream) throws IOException JavaDoc {
230         save(templates, new StreamResult JavaDoc(stream));
231     }
232
233     /**
234      * Saves the templates as XML.
235      *
236      * @param templates the templates to save
237      * @param writer the writer to write the templates to in XML
238      * @throws IOException if writing the templates fails
239      */

240     public void save(TemplatePersistenceData[] templates, Writer JavaDoc writer) throws IOException JavaDoc {
241         save(templates, new StreamResult JavaDoc(writer));
242     }
243
244     /**
245      * Saves the templates as XML.
246      *
247      * @param templates the templates to save
248      * @param result the stream result to write to
249      * @throws IOException if writing the templates fails
250      */

251     private void save(TemplatePersistenceData[] templates, StreamResult JavaDoc result) throws IOException JavaDoc {
252         try {
253             DocumentBuilderFactory JavaDoc factory= DocumentBuilderFactory.newInstance();
254             DocumentBuilder JavaDoc builder= factory.newDocumentBuilder();
255             Document JavaDoc document= builder.newDocument();
256
257             Node JavaDoc root= document.createElement(TEMPLATE_ROOT);
258             document.appendChild(root);
259
260             for (int i= 0; i < templates.length; i++) {
261                 TemplatePersistenceData data= templates[i];
262                 Template template= data.getTemplate();
263
264                 Node JavaDoc node= document.createElement(TEMPLATE_ELEMENT);
265                 root.appendChild(node);
266
267                 NamedNodeMap JavaDoc attributes= node.getAttributes();
268
269                 String JavaDoc id= data.getId();
270                 if (id != null) {
271                     Attr JavaDoc idAttr= document.createAttribute(ID_ATTRIBUTE);
272                     idAttr.setValue(id);
273                     attributes.setNamedItem(idAttr);
274                 }
275
276                 if (template != null) {
277                     Attr JavaDoc name= document.createAttribute(NAME_ATTRIBUTE);
278                     name.setValue(template.getName());
279                     attributes.setNamedItem(name);
280                 }
281
282                 if (template != null) {
283                     Attr JavaDoc description= document.createAttribute(DESCRIPTION_ATTRIBUTE);
284                     description.setValue(template.getDescription());
285                     attributes.setNamedItem(description);
286                 }
287
288                 if (template != null) {
289                     Attr JavaDoc context= document.createAttribute(CONTEXT_ATTRIBUTE);
290                     context.setValue(template.getContextTypeId());
291                     attributes.setNamedItem(context);
292                 }
293
294                 Attr JavaDoc enabled= document.createAttribute(ENABLED_ATTRIBUTE);
295                 enabled.setValue(data.isEnabled() ? Boolean.toString(true) : Boolean.toString(false));
296                 attributes.setNamedItem(enabled);
297
298                 Attr JavaDoc deleted= document.createAttribute(DELETED_ATTRIBUTE);
299                 deleted.setValue(data.isDeleted() ? Boolean.toString(true) : Boolean.toString(false));
300                 attributes.setNamedItem(deleted);
301
302                 if (template != null) {
303                     Attr JavaDoc autoInsertable= document.createAttribute(AUTO_INSERTABLE_ATTRIBUTE);
304                     autoInsertable.setValue(template.isAutoInsertable() ? Boolean.toString(true) : Boolean.toString(false));
305                     attributes.setNamedItem(autoInsertable);
306                 }
307
308                 if (template != null) {
309                     Text JavaDoc pattern= document.createTextNode(template.getPattern());
310                     node.appendChild(pattern);
311                 }
312             }
313
314
315             Transformer JavaDoc transformer=TransformerFactory.newInstance().newTransformer();
316             transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
317
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
318
DOMSource JavaDoc source = new DOMSource JavaDoc(document);
319
320             transformer.transform(source, result);
321
322         } catch (ParserConfigurationException JavaDoc e) {
323             Assert.isTrue(false);
324         } catch (TransformerException JavaDoc e) {
325             if (e.getException() instanceof IOException JavaDoc)
326                 throw (IOException JavaDoc) e.getException();
327             Assert.isTrue(false);
328         }
329     }
330
331     private boolean getBooleanValue(NamedNodeMap JavaDoc attributes, String JavaDoc attribute, boolean defaultValue) throws SAXException JavaDoc {
332         Node JavaDoc enabledNode= attributes.getNamedItem(attribute);
333         if (enabledNode == null)
334             return defaultValue;
335         else if (enabledNode.getNodeValue().equals(Boolean.toString(true)))
336             return true;
337         else if (enabledNode.getNodeValue().equals(Boolean.toString(false)))
338             return false;
339         else
340             throw new SAXException JavaDoc(TemplatePersistenceMessages.getString("TemplateReaderWriter.error.illegal_boolean_attribute")); //$NON-NLS-1$
341
}
342
343     private String JavaDoc getStringValue(NamedNodeMap JavaDoc attributes, String JavaDoc name) throws SAXException JavaDoc {
344         String JavaDoc val= getStringValue(attributes, name, null);
345         if (val == null)
346             throw new SAXException JavaDoc(TemplatePersistenceMessages.getString("TemplateReaderWriter.error.missing_attribute")); //$NON-NLS-1$
347
return val;
348     }
349
350     private String JavaDoc getStringValue(NamedNodeMap JavaDoc attributes, String JavaDoc name, String JavaDoc defaultValue) {
351         Node JavaDoc node= attributes.getNamedItem(name);
352         return node == null ? defaultValue : node.getNodeValue();
353     }
354
355     private String JavaDoc translateString(String JavaDoc str, ResourceBundle JavaDoc bundle) {
356         if (bundle == null)
357             return str;
358
359         int idx= str.indexOf('%');
360         if (idx == -1) {
361             return str;
362         }
363         StringBuffer JavaDoc buf= new StringBuffer JavaDoc();
364         int k= 0;
365         while (idx != -1) {
366             buf.append(str.substring(k, idx));
367             for (k= idx + 1; k < str.length() && !Character.isWhitespace(str.charAt(k)); k++) {
368                 // loop
369
}
370             String JavaDoc key= str.substring(idx + 1, k);
371             buf.append(getBundleString(key, bundle));
372             idx= str.indexOf('%', k);
373         }
374         buf.append(str.substring(k));
375         return buf.toString();
376     }
377
378     private String JavaDoc getBundleString(String JavaDoc key, ResourceBundle JavaDoc bundle) {
379         if (bundle != null) {
380             try {
381                 return bundle.getString(key);
382             } catch (MissingResourceException JavaDoc e) {
383                 return '!' + key + '!';
384             }
385         }
386         return TemplatePersistenceMessages.getString(key); // default messages
387
}
388 }
389
390
Popular Tags