KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > preferences > formatter > ProfileStore


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
12 package org.eclipse.jdt.internal.ui.preferences.formatter;
13
14 import java.io.ByteArrayInputStream JavaDoc;
15 import java.io.ByteArrayOutputStream JavaDoc;
16 import java.io.File JavaDoc;
17 import java.io.FileInputStream JavaDoc;
18 import java.io.FileOutputStream JavaDoc;
19 import java.io.IOException JavaDoc;
20 import java.io.InputStream JavaDoc;
21 import java.io.OutputStream JavaDoc;
22 import java.io.UnsupportedEncodingException JavaDoc;
23 import java.util.ArrayList JavaDoc;
24 import java.util.Collection JavaDoc;
25 import java.util.HashMap JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.List JavaDoc;
28 import java.util.Map JavaDoc;
29
30 import javax.xml.parsers.DocumentBuilder JavaDoc;
31 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
32 import javax.xml.parsers.ParserConfigurationException JavaDoc;
33 import javax.xml.parsers.SAXParser JavaDoc;
34 import javax.xml.parsers.SAXParserFactory JavaDoc;
35 import javax.xml.transform.OutputKeys JavaDoc;
36 import javax.xml.transform.Transformer JavaDoc;
37 import javax.xml.transform.TransformerException JavaDoc;
38 import javax.xml.transform.TransformerFactory JavaDoc;
39 import javax.xml.transform.dom.DOMSource JavaDoc;
40 import javax.xml.transform.stream.StreamResult JavaDoc;
41
42 import org.eclipse.core.runtime.CoreException;
43 import org.eclipse.core.runtime.IStatus;
44 import org.eclipse.core.runtime.preferences.IEclipsePreferences;
45 import org.eclipse.core.runtime.preferences.IScopeContext;
46
47 import org.eclipse.jdt.ui.JavaUI;
48
49 import org.eclipse.jdt.internal.ui.JavaPlugin;
50 import org.eclipse.jdt.internal.ui.JavaUIException;
51 import org.eclipse.jdt.internal.ui.JavaUIStatus;
52 import org.eclipse.jdt.internal.ui.preferences.formatter.ProfileManager.CustomProfile;
53 import org.eclipse.jdt.internal.ui.preferences.formatter.ProfileManager.Profile;
54
55 import org.w3c.dom.Document JavaDoc;
56 import org.w3c.dom.Element JavaDoc;
57 import org.xml.sax.Attributes JavaDoc;
58 import org.xml.sax.InputSource JavaDoc;
59 import org.xml.sax.SAXException JavaDoc;
60 import org.xml.sax.helpers.DefaultHandler JavaDoc;
61
62
63 /**
64  * Can load/store profiles from/to profilesKey
65  */

66 public class ProfileStore {
67
68     /** The default encoding to use */
69     public static final String JavaDoc ENCODING= "UTF-8"; //$NON-NLS-1$
70

71     protected static final String JavaDoc VERSION_KEY_SUFFIX= ".version"; //$NON-NLS-1$
72

73     /**
74      * A SAX event handler to parse the xml format for profiles.
75      */

76     private final static class ProfileDefaultHandler extends DefaultHandler JavaDoc {
77         
78         private List JavaDoc fProfiles;
79         private int fVersion;
80         
81         private String JavaDoc fName;
82         private Map JavaDoc fSettings;
83         private String JavaDoc fKind;
84
85         public void startElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName, Attributes JavaDoc attributes) throws SAXException JavaDoc {
86
87             if (qName.equals(XML_NODE_SETTING)) {
88
89                 final String JavaDoc key= attributes.getValue(XML_ATTRIBUTE_ID);
90                 final String JavaDoc value= attributes.getValue(XML_ATTRIBUTE_VALUE);
91                 fSettings.put(key, value);
92
93             } else if (qName.equals(XML_NODE_PROFILE)) {
94
95                 fName= attributes.getValue(XML_ATTRIBUTE_NAME);
96                 fKind= attributes.getValue(XML_ATTRIBUTE_PROFILE_KIND);
97                 if (fKind == null) //Can only be an CodeFormatterProfile created pre 3.3M2
98
fKind= ProfileVersioner.CODE_FORMATTER_PROFILE_KIND;
99                 
100                 fSettings= new HashMap JavaDoc(200);
101
102             }
103             else if (qName.equals(XML_NODE_ROOT)) {
104
105                 fProfiles= new ArrayList JavaDoc();
106                 try {
107                     fVersion= Integer.parseInt(attributes.getValue(XML_ATTRIBUTE_VERSION));
108                 } catch (NumberFormatException JavaDoc ex) {
109                     throw new SAXException JavaDoc(ex);
110                 }
111
112             }
113         }
114         
115         public void endElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName) {
116             if (qName.equals(XML_NODE_PROFILE)) {
117                 fProfiles.add(new CustomProfile(fName, fSettings, fVersion, fKind));
118                 fName= null;
119                 fSettings= null;
120                 fKind= null;
121             }
122         }
123         
124         public List JavaDoc getProfiles() {
125             return fProfiles;
126         }
127         
128     }
129     
130     /**
131      * Identifiers for the XML file.
132      */

133     private final static String JavaDoc XML_NODE_ROOT= "profiles"; //$NON-NLS-1$
134
private final static String JavaDoc XML_NODE_PROFILE= "profile"; //$NON-NLS-1$
135
private final static String JavaDoc XML_NODE_SETTING= "setting"; //$NON-NLS-1$
136

137     private final static String JavaDoc XML_ATTRIBUTE_VERSION= "version"; //$NON-NLS-1$
138
private final static String JavaDoc XML_ATTRIBUTE_ID= "id"; //$NON-NLS-1$
139
private final static String JavaDoc XML_ATTRIBUTE_NAME= "name"; //$NON-NLS-1$
140
private final static String JavaDoc XML_ATTRIBUTE_PROFILE_KIND= "kind"; //$NON-NLS-1$
141
private final static String JavaDoc XML_ATTRIBUTE_VALUE= "value"; //$NON-NLS-1$
142

143     private final IProfileVersioner fProfileVersioner;
144     private final String JavaDoc fProfilesKey;
145     private final String JavaDoc fProfilesVersionKey;
146         
147     
148     public ProfileStore(String JavaDoc profilesKey, IProfileVersioner profileVersioner) {
149         fProfilesKey= profilesKey;
150         fProfileVersioner= profileVersioner;
151         fProfilesVersionKey= profilesKey + VERSION_KEY_SUFFIX;
152     }
153     
154     /**
155      * @return Returns the collection of profiles currently stored in the preference store or
156      * <code>null</code> if the loading failed. The elements are of type {@link ProfileManager.CustomProfile}
157      * and are all updated to the latest version.
158      * @throws CoreException
159      */

160     public List JavaDoc readProfiles(IScopeContext scope) throws CoreException {
161         return readProfilesFromString(scope.getNode(JavaUI.ID_PLUGIN).get(fProfilesKey, null));
162     }
163     
164     public void writeProfiles(Collection JavaDoc profiles, IScopeContext instanceScope) throws CoreException {
165         ByteArrayOutputStream JavaDoc stream= new ByteArrayOutputStream JavaDoc(2000);
166         try {
167             writeProfilesToStream(profiles, stream, ENCODING, fProfileVersioner);
168             String JavaDoc val;
169             try {
170                 val= stream.toString(ENCODING);
171             } catch (UnsupportedEncodingException JavaDoc e) {
172                 val= stream.toString();
173             }
174             IEclipsePreferences uiPreferences = instanceScope.getNode(JavaUI.ID_PLUGIN);
175             uiPreferences.put(fProfilesKey, val);
176             uiPreferences.putInt(fProfilesVersionKey, fProfileVersioner.getCurrentVersion());
177         } finally {
178             try { stream.close(); } catch (IOException JavaDoc e) { /* ignore */ }
179         }
180     }
181     
182     public List JavaDoc readProfilesFromString(String JavaDoc profiles) throws CoreException {
183         if (profiles != null && profiles.length() > 0) {
184             byte[] bytes;
185             try {
186                 bytes= profiles.getBytes(ENCODING);
187             } catch (UnsupportedEncodingException JavaDoc e) {
188                 bytes= profiles.getBytes();
189             }
190             InputStream JavaDoc is= new ByteArrayInputStream JavaDoc(bytes);
191             try {
192                 List JavaDoc res= readProfilesFromStream(new InputSource JavaDoc(is));
193                 if (res != null) {
194                     for (int i= 0; i < res.size(); i++) {
195                         fProfileVersioner.update((CustomProfile) res.get(i));
196                     }
197                 }
198                 return res;
199             } finally {
200                 try { is.close(); } catch (IOException JavaDoc e) { /* ignore */ }
201             }
202         }
203         return null;
204     }
205     
206     
207     /**
208      * Read the available profiles from the internal XML file and return them
209      * as collection or <code>null</code> if the file is not a profile file.
210      * @param file The file to read from
211      * @return returns a list of <code>CustomProfile</code> or <code>null</code>
212      * @throws CoreException
213      */

214     public List JavaDoc readProfilesFromFile(File JavaDoc file) throws CoreException {
215         try {
216             final FileInputStream JavaDoc reader= new FileInputStream JavaDoc(file);
217             try {
218                 return readProfilesFromStream(new InputSource JavaDoc(reader));
219             } finally {
220                 try { reader.close(); } catch (IOException JavaDoc e) { /* ignore */ }
221             }
222         } catch (IOException JavaDoc e) {
223             throw createException(e, FormatterMessages.CodingStyleConfigurationBlock_error_reading_xml_message);
224         }
225     }
226     
227     /**
228      * Load profiles from a XML stream and add them to a map or <code>null</code> if the source is not a profile store.
229      * @param inputSource The input stream
230      * @return returns a list of <code>CustomProfile</code> or <code>null</code>
231      * @throws CoreException
232      */

233     public static List JavaDoc readProfilesFromStream(InputSource JavaDoc inputSource) throws CoreException {
234         
235         final ProfileDefaultHandler handler= new ProfileDefaultHandler();
236         try {
237             final SAXParserFactory JavaDoc factory= SAXParserFactory.newInstance();
238             final SAXParser JavaDoc parser= factory.newSAXParser();
239             parser.parse(inputSource, handler);
240         } catch (SAXException JavaDoc e) {
241             throw createException(e, FormatterMessages.CodingStyleConfigurationBlock_error_reading_xml_message);
242         } catch (IOException JavaDoc e) {
243             throw createException(e, FormatterMessages.CodingStyleConfigurationBlock_error_reading_xml_message);
244         } catch (ParserConfigurationException JavaDoc e) {
245             throw createException(e, FormatterMessages.CodingStyleConfigurationBlock_error_reading_xml_message);
246         }
247         return handler.getProfiles();
248     }
249     
250     /**
251      * Write the available profiles to the internal XML file.
252      * @param profiles List of <code>CustomProfile</code>
253      * @param file File to write
254      * @param encoding the encoding to use
255      * @throws CoreException
256      */

257     public void writeProfilesToFile(Collection JavaDoc profiles, File JavaDoc file, String JavaDoc encoding) throws CoreException {
258         final OutputStream JavaDoc stream;
259         try {
260             stream= new FileOutputStream JavaDoc(file);
261             try {
262                 writeProfilesToStream(profiles, stream, encoding, fProfileVersioner);
263             } finally {
264                 try { stream.close(); } catch (IOException JavaDoc e) { /* ignore */ }
265             }
266         } catch (IOException JavaDoc e) {
267             throw createException(e, FormatterMessages.CodingStyleConfigurationBlock_error_serializing_xml_message);
268         }
269     }
270     
271     /**
272      * Save profiles to an XML stream
273      * @param profiles the list of <code>CustomProfile</code>
274      * @param stream the stream to write to
275      * @param encoding the encoding to use
276      * @throws CoreException
277      */

278     public static void writeProfilesToStream(Collection JavaDoc profiles, OutputStream JavaDoc stream, String JavaDoc encoding, IProfileVersioner profileVersioner) throws CoreException {
279
280         try {
281             final DocumentBuilderFactory JavaDoc factory= DocumentBuilderFactory.newInstance();
282             final DocumentBuilder JavaDoc builder= factory.newDocumentBuilder();
283             final Document JavaDoc document= builder.newDocument();
284             
285             final Element JavaDoc rootElement = document.createElement(XML_NODE_ROOT);
286             rootElement.setAttribute(XML_ATTRIBUTE_VERSION, Integer.toString(profileVersioner.getCurrentVersion()));
287
288             document.appendChild(rootElement);
289             
290             for(final Iterator JavaDoc iter= profiles.iterator(); iter.hasNext();) {
291                 final Profile profile= (Profile)iter.next();
292                 if (profile.isProfileToSave()) {
293                     final Element JavaDoc profileElement= createProfileElement(profile, document, profileVersioner);
294                     rootElement.appendChild(profileElement);
295                 }
296             }
297
298             Transformer JavaDoc transformer=TransformerFactory.newInstance().newTransformer();
299             transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
300
transformer.setOutputProperty(OutputKeys.ENCODING, encoding);
301             transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
302
transformer.transform(new DOMSource JavaDoc(document), new StreamResult JavaDoc(stream));
303         } catch (TransformerException JavaDoc e) {
304             throw createException(e, FormatterMessages.CodingStyleConfigurationBlock_error_serializing_xml_message);
305         } catch (ParserConfigurationException JavaDoc e) {
306             throw createException(e, FormatterMessages.CodingStyleConfigurationBlock_error_serializing_xml_message);
307         }
308     }
309
310     
311     /*
312      * Create a new profile element in the specified document. The profile is not added
313      * to the document by this method.
314      */

315     private static Element JavaDoc createProfileElement(Profile profile, Document JavaDoc document, IProfileVersioner profileVersioner) {
316         final Element JavaDoc element= document.createElement(XML_NODE_PROFILE);
317         element.setAttribute(XML_ATTRIBUTE_NAME, profile.getName());
318         element.setAttribute(XML_ATTRIBUTE_VERSION, Integer.toString(profile.getVersion()));
319         element.setAttribute(XML_ATTRIBUTE_PROFILE_KIND, profileVersioner.getProfileKind());
320         
321         final Iterator JavaDoc keyIter= profile.getSettings().keySet().iterator();
322         
323         while (keyIter.hasNext()) {
324             final String JavaDoc key= (String JavaDoc)keyIter.next();
325             final String JavaDoc value= (String JavaDoc)profile.getSettings().get(key);
326             if (value != null) {
327                 final Element JavaDoc setting= document.createElement(XML_NODE_SETTING);
328                 setting.setAttribute(XML_ATTRIBUTE_ID, key);
329                 setting.setAttribute(XML_ATTRIBUTE_VALUE, value);
330                 element.appendChild(setting);
331             } else {
332                 JavaPlugin.logErrorMessage("ProfileStore: Profile does not contain value for key " + key); //$NON-NLS-1$
333
}
334         }
335         return element;
336     }
337     
338         
339     /*
340      * Creates a UI exception for logging purposes
341      */

342     private static JavaUIException createException(Throwable JavaDoc t, String JavaDoc message) {
343         return new JavaUIException(JavaUIStatus.createError(IStatus.ERROR, message, t));
344     }
345 }
346
Popular Tags