KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > corext > util > History


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.jdt.internal.corext.util;
12
13 import java.io.File JavaDoc;
14 import java.io.FileInputStream JavaDoc;
15 import java.io.FileOutputStream JavaDoc;
16 import java.io.IOException JavaDoc;
17 import java.io.InputStreamReader JavaDoc;
18 import java.io.OutputStream JavaDoc;
19 import java.util.Collection JavaDoc;
20 import java.util.Hashtable JavaDoc;
21 import java.util.Iterator JavaDoc;
22 import java.util.LinkedHashMap JavaDoc;
23 import java.util.Map JavaDoc;
24 import java.util.Set JavaDoc;
25
26 import javax.xml.parsers.DocumentBuilder JavaDoc;
27 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
28 import javax.xml.parsers.ParserConfigurationException JavaDoc;
29 import javax.xml.transform.OutputKeys JavaDoc;
30 import javax.xml.transform.Transformer JavaDoc;
31 import javax.xml.transform.TransformerException JavaDoc;
32 import javax.xml.transform.TransformerFactory JavaDoc;
33 import javax.xml.transform.TransformerFactoryConfigurationError JavaDoc;
34 import javax.xml.transform.dom.DOMSource JavaDoc;
35 import javax.xml.transform.stream.StreamResult JavaDoc;
36
37 import org.eclipse.core.runtime.CoreException;
38 import org.eclipse.core.runtime.IPath;
39 import org.eclipse.core.runtime.IStatus;
40
41 import org.eclipse.jdt.internal.corext.CorextMessages;
42
43 import org.eclipse.jdt.internal.ui.JavaPlugin;
44 import org.eclipse.jdt.internal.ui.JavaUIException;
45 import org.eclipse.jdt.internal.ui.JavaUIStatus;
46
47 import org.w3c.dom.Document JavaDoc;
48 import org.w3c.dom.Element JavaDoc;
49 import org.w3c.dom.Node JavaDoc;
50 import org.w3c.dom.NodeList JavaDoc;
51 import org.xml.sax.InputSource JavaDoc;
52 import org.xml.sax.SAXException JavaDoc;
53
54 /**
55  * History stores a list of key, object pairs. The list is bounded at size
56  * MAX_HISTORY_SIZE. If the list exceeds this size the eldest element is removed
57  * from the list. An element can be added/renewed with a call to <code>accessed(Object)</code>.
58  *
59  * The history can be stored to/loaded from an xml file.
60  */

61 public abstract class History {
62
63     private static final String JavaDoc DEFAULT_ROOT_NODE_NAME= "histroyRootNode"; //$NON-NLS-1$
64
private static final String JavaDoc DEFAULT_INFO_NODE_NAME= "infoNode"; //$NON-NLS-1$
65
private static final int MAX_HISTORY_SIZE= 60;
66
67     private static JavaUIException createException(Throwable JavaDoc t, String JavaDoc message) {
68         return new JavaUIException(JavaUIStatus.createError(IStatus.ERROR, message, t));
69     }
70
71     private final Map JavaDoc fHistory;
72     private final Hashtable JavaDoc fPositions;
73     private final String JavaDoc fFileName;
74     private final String JavaDoc fRootNodeName;
75     private final String JavaDoc fInfoNodeName;
76         
77     public History(String JavaDoc fileName, String JavaDoc rootNodeName, String JavaDoc infoNodeName) {
78         fHistory= new LinkedHashMap JavaDoc(80, 0.75f, true) {
79             private static final long serialVersionUID= 1L;
80             protected boolean removeEldestEntry(Map.Entry JavaDoc eldest) {
81                 return size() > MAX_HISTORY_SIZE;
82             }
83         };
84         fFileName= fileName;
85         fRootNodeName= rootNodeName;
86         fInfoNodeName= infoNodeName;
87         fPositions= new Hashtable JavaDoc(MAX_HISTORY_SIZE);
88     }
89     
90     public History(String JavaDoc fileName) {
91         this(fileName, DEFAULT_ROOT_NODE_NAME, DEFAULT_INFO_NODE_NAME);
92     }
93     
94     public synchronized void accessed(Object JavaDoc object) {
95         fHistory.put(getKey(object), object);
96         rebuildPositions();
97     }
98     
99     public synchronized boolean contains(Object JavaDoc object) {
100         return fHistory.containsKey(getKey(object));
101     }
102     
103     public synchronized boolean containsKey(Object JavaDoc key) {
104         return fHistory.containsKey(key);
105     }
106     
107     public synchronized boolean isEmpty() {
108         return fHistory.isEmpty();
109     }
110     
111     public synchronized Object JavaDoc remove(Object JavaDoc object) {
112         Object JavaDoc removed= fHistory.remove(getKey(object));
113         rebuildPositions();
114         return removed;
115     }
116     
117     public synchronized Object JavaDoc removeKey(Object JavaDoc key) {
118         Object JavaDoc removed= fHistory.remove(key);
119         rebuildPositions();
120         return removed;
121     }
122     
123     /**
124      * Normalized position in history of object denoted by key.
125      * The position is a value between zero and one where zero
126      * means not contained in history and one means newest element
127      * in history. The lower the value the older the element.
128      *
129      * @param key The key of the object to inspect
130      * @return value in [0.0, 1.0] the lower the older the element
131      */

132     public synchronized float getNormalizedPosition(Object JavaDoc key) {
133         if (!containsKey(key))
134             return 0.0f;
135
136         int pos= ((Integer JavaDoc)fPositions.get(key)).intValue() + 1;
137         
138         //containsKey(key) implies fHistory.size()>0
139
return (float)pos / (float)fHistory.size();
140     }
141     
142     /**
143      * Absolute position of object denoted by key in the
144      * history or -1 if !containsKey(key). The higher the
145      * newer.
146      *
147      * @param key The key of the object to inspect
148      * @return value between 0 and MAX_HISTORY_SIZE - 1, or -1
149      */

150     public synchronized int getPosition(Object JavaDoc key) {
151         if (!containsKey(key))
152             return -1;
153         
154         return ((Integer JavaDoc)fPositions.get(key)).intValue();
155     }
156
157     public synchronized void load() {
158         IPath stateLocation= JavaPlugin.getDefault().getStateLocation().append(fFileName);
159         File JavaDoc file= new File JavaDoc(stateLocation.toOSString());
160         if (file.exists()) {
161             InputStreamReader JavaDoc reader= null;
162             try {
163                 reader = new InputStreamReader JavaDoc(new FileInputStream JavaDoc(file), "utf-8");//$NON-NLS-1$
164
load(new InputSource JavaDoc(reader));
165             } catch (IOException JavaDoc e) {
166                 JavaPlugin.log(e);
167             } catch (CoreException e) {
168                 JavaPlugin.log(e);
169             } finally {
170                 try {
171                     if (reader != null)
172                         reader.close();
173                 } catch (IOException JavaDoc e) {
174                     JavaPlugin.log(e);
175                 }
176             }
177         }
178     }
179     
180     public synchronized void save() {
181         IPath stateLocation= JavaPlugin.getDefault().getStateLocation().append(fFileName);
182         File JavaDoc file= new File JavaDoc(stateLocation.toOSString());
183         OutputStream JavaDoc out= null;
184         try {
185             out= new FileOutputStream JavaDoc(file);
186             save(out);
187         } catch (IOException JavaDoc e) {
188             JavaPlugin.log(e);
189         } catch (CoreException e) {
190             JavaPlugin.log(e);
191         } catch (TransformerFactoryConfigurationError JavaDoc e) {
192             // The XML library can be misconficgured (e.g. via
193
// -Djava.endorsed.dirs=C:\notExisting\xerces-2_7_1)
194
JavaPlugin.log(e);
195         } finally {
196             try {
197                 if (out != null) {
198                     out.close();
199                 }
200             } catch (IOException JavaDoc e) {
201                 JavaPlugin.log(e);
202             }
203         }
204     }
205     
206     protected Set JavaDoc getKeys() {
207         return fHistory.keySet();
208     }
209     
210     protected Collection JavaDoc getValues() {
211         return fHistory.values();
212     }
213     
214     /**
215      * Store <code>Object</code> in <code>Element</code>
216      *
217      * @param object The object to store
218      * @param element The Element to store to
219      */

220     protected abstract void setAttributes(Object JavaDoc object, Element JavaDoc element);
221     
222     /**
223      * Return a new instance of an Object given <code>element</code>
224      *
225      * @param element The element containing required information to create the Object
226      */

227     protected abstract Object JavaDoc createFromElement(Element JavaDoc element);
228     
229     /**
230      * Get key for object
231      *
232      * @param object The object to calculate a key for, not null
233      * @return The key for object, not null
234      */

235     protected abstract Object JavaDoc getKey(Object JavaDoc object);
236     
237     private void rebuildPositions() {
238         fPositions.clear();
239         Collection JavaDoc values= fHistory.values();
240         int pos=0;
241         for (Iterator JavaDoc iter= values.iterator(); iter.hasNext();) {
242             Object JavaDoc element= iter.next();
243             fPositions.put(getKey(element), new Integer JavaDoc(pos));
244             pos++;
245         }
246     }
247
248     private void load(InputSource JavaDoc inputSource) throws CoreException {
249         Element JavaDoc root;
250         try {
251             DocumentBuilder JavaDoc parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
252             root = parser.parse(inputSource).getDocumentElement();
253         } catch (SAXException JavaDoc e) {
254             throw createException(e, Messages.format(CorextMessages.History_error_read, fFileName));
255         } catch (ParserConfigurationException JavaDoc e) {
256             throw createException(e, Messages.format(CorextMessages.History_error_read, fFileName));
257         } catch (IOException JavaDoc e) {
258             throw createException(e, Messages.format(CorextMessages.History_error_read, fFileName));
259         }
260         
261         if (root == null) return;
262         if (!root.getNodeName().equalsIgnoreCase(fRootNodeName)) {
263             return;
264         }
265         NodeList JavaDoc list= root.getChildNodes();
266         int length= list.getLength();
267         for (int i= 0; i < length; ++i) {
268             Node JavaDoc node= list.item(i);
269             if (node.getNodeType() == Node.ELEMENT_NODE) {
270                 Element JavaDoc type= (Element JavaDoc) node;
271                 if (type.getNodeName().equalsIgnoreCase(fInfoNodeName)) {
272                     Object JavaDoc object= createFromElement(type);
273                     if (object != null) {
274                         fHistory.put(getKey(object), object);
275                     }
276                 }
277             }
278         }
279         rebuildPositions();
280     }
281     
282     private void save(OutputStream JavaDoc stream) throws CoreException {
283         try {
284             DocumentBuilderFactory JavaDoc factory= DocumentBuilderFactory.newInstance();
285             DocumentBuilder JavaDoc builder= factory.newDocumentBuilder();
286             Document JavaDoc document= builder.newDocument();
287             
288             Element JavaDoc rootElement = document.createElement(fRootNodeName);
289             document.appendChild(rootElement);
290     
291             Iterator JavaDoc values= getValues().iterator();
292             while (values.hasNext()) {
293                 Object JavaDoc object= values.next();
294                 Element JavaDoc element= document.createElement(fInfoNodeName);
295                 setAttributes(object, element);
296                 rootElement.appendChild(element);
297             }
298             
299             Transformer JavaDoc transformer=TransformerFactory.newInstance().newTransformer();
300             transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
301
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
302
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
303
DOMSource JavaDoc source = new DOMSource JavaDoc(document);
304             StreamResult JavaDoc result = new StreamResult JavaDoc(stream);
305
306             transformer.transform(source, result);
307         } catch (TransformerException JavaDoc e) {
308             throw createException(e, Messages.format(CorextMessages.History_error_serialize, fFileName));
309         } catch (ParserConfigurationException JavaDoc e) {
310             throw createException(e, Messages.format(CorextMessages.History_error_serialize, fFileName));
311         }
312     }
313
314 }
315
Popular Tags