1 11 package org.eclipse.jdt.internal.corext.util; 12 13 import java.io.File ; 14 import java.io.FileInputStream ; 15 import java.io.FileOutputStream ; 16 import java.io.IOException ; 17 import java.io.InputStreamReader ; 18 import java.io.OutputStream ; 19 import java.util.ArrayList ; 20 import java.util.Collection ; 21 import java.util.Collections ; 22 import java.util.Iterator ; 23 import java.util.LinkedHashMap ; 24 import java.util.List ; 25 import java.util.Map ; 26 import java.util.StringTokenizer ; 27 28 import javax.xml.parsers.DocumentBuilder ; 29 import javax.xml.parsers.DocumentBuilderFactory ; 30 import javax.xml.parsers.ParserConfigurationException ; 31 import javax.xml.transform.OutputKeys ; 32 import javax.xml.transform.Transformer ; 33 import javax.xml.transform.TransformerException ; 34 import javax.xml.transform.TransformerFactory ; 35 import javax.xml.transform.dom.DOMSource ; 36 import javax.xml.transform.stream.StreamResult ; 37 38 import org.eclipse.core.runtime.CoreException; 39 import org.eclipse.core.runtime.IPath; 40 import org.eclipse.core.runtime.IProgressMonitor; 41 import org.eclipse.core.runtime.IStatus; 42 43 import org.eclipse.jdt.core.IType; 44 import org.eclipse.jdt.core.JavaModelException; 45 import org.eclipse.jdt.core.search.IJavaSearchScope; 46 import org.eclipse.jdt.core.search.SearchEngine; 47 48 import org.eclipse.jdt.internal.corext.CorextMessages; 49 50 import org.eclipse.jdt.internal.ui.JavaPlugin; 51 import org.eclipse.jdt.internal.ui.JavaUIException; 52 import org.eclipse.jdt.internal.ui.JavaUIStatus; 53 54 import org.w3c.dom.Document ; 55 import org.w3c.dom.Element ; 56 import org.w3c.dom.Node ; 57 import org.w3c.dom.NodeList ; 58 import org.xml.sax.InputSource ; 59 import org.xml.sax.SAXException ; 60 61 public class TypeInfoHistory { 62 63 private static final String NODE_ROOT= "typeInfoHistroy"; private static final String NODE_TYPE_INFO= "typeInfo"; private static final String NODE_NAME= "name"; private static final String NODE_PACKAGE= "package"; private static final String NODE_ENCLOSING_NAMES= "enclosingTypes"; private static final String NODE_PATH= "path"; private static final String NODE_MODIFIERS= "modifiers"; 71 private static final char[][] EMPTY_ENCLOSING_NAMES= new char[0][0]; 72 73 private Map fHistroy= new LinkedHashMap (80, 0.75f, true) { 74 private static final long serialVersionUID= 1L; 75 protected boolean removeEldestEntry(Map.Entry eldest) { 76 return size() > 60; 77 } 78 }; 79 80 private static final String FILENAME= "TypeInfoHistory.xml"; private static TypeInfoHistory fgInstance; 82 83 public static synchronized TypeInfoHistory getInstance() { 84 if (fgInstance == null) 85 fgInstance= new TypeInfoHistory(); 86 return fgInstance; 87 } 88 89 private TypeInfoHistory() { 90 load(); 91 } 92 93 public synchronized boolean isEmpty() { 94 return fHistroy.isEmpty(); 95 } 96 97 public synchronized boolean contains(TypeInfo type) { 98 return fHistroy.get(type) != null; 99 } 100 101 public synchronized void checkConsistency(IProgressMonitor monitor) { 102 IJavaSearchScope scope= SearchEngine.createWorkspaceScope(); 103 List keys= new ArrayList (fHistroy.keySet()); 104 monitor.beginTask(CorextMessages.TypeInfoHistory_consistency_check, keys.size()); 105 monitor.setTaskName(CorextMessages.TypeInfoHistory_consistency_check); 106 for (Iterator iter= keys.iterator(); iter.hasNext();) { 107 TypeInfo type= (TypeInfo)iter.next(); 108 try { 109 IType jType= type.resolveType(scope); 110 if (jType == null || !jType.exists()) 111 fHistroy.remove(type); 112 } catch (JavaModelException e) { 113 fHistroy.remove(type); 114 } 115 monitor.worked(1); 116 } 117 monitor.done(); 118 } 119 120 public synchronized void accessed(TypeInfo info) { 121 fHistroy.put(info, info); 122 } 123 124 public synchronized TypeInfo remove(TypeInfo info) { 125 return (TypeInfo)fHistroy.remove(info); 126 } 127 128 public synchronized TypeInfo[] getTypeInfos() { 129 Collection values= fHistroy.values(); 130 int size= values.size(); 131 TypeInfo[] result= new TypeInfo[size]; 132 int i= size - 1; 133 for (Iterator iter= values.iterator(); iter.hasNext();) { 134 result[i]= (TypeInfo)iter.next(); 135 i--; 136 } 137 return result; 138 } 139 140 public synchronized TypeInfo[] getFilteredTypeInfos(TypeInfoFilter filter) { 141 Collection values= fHistroy.values(); 142 List result= new ArrayList (); 143 for (Iterator iter= values.iterator(); iter.hasNext();) { 144 TypeInfo type= (TypeInfo)iter.next(); 145 if ((filter == null || filter.matchesHistoryElement(type)) && !TypeFilter.isFiltered(type.getFullyQualifiedName())) 146 result.add(type); 147 } 148 Collections.reverse(result); 149 return (TypeInfo[])result.toArray(new TypeInfo[result.size()]); 150 151 } 152 153 private void load() { 154 IPath stateLocation= JavaPlugin.getDefault().getStateLocation().append(FILENAME); 155 File file= new File (stateLocation.toOSString()); 156 if (file.exists()) { 157 InputStreamReader reader= null; 158 try { 159 reader = new InputStreamReader (new FileInputStream (file), "utf-8"); load(new InputSource (reader)); 161 } catch (IOException e) { 162 JavaPlugin.log(e); 163 } catch (CoreException e) { 164 JavaPlugin.log(e); 165 } finally { 166 try { 167 if (reader != null) 168 reader.close(); 169 } catch (IOException e) { 170 JavaPlugin.log(e); 171 } 172 } 173 } 174 } 175 176 private void load(InputSource inputSource) throws CoreException { 177 TypeInfoFactory factory= new TypeInfoFactory(); 178 Element root; 179 try { 180 DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 181 root = parser.parse(inputSource).getDocumentElement(); 182 } catch (SAXException e) { 183 throw createException(e, CorextMessages.TypeInfoHistory_error_read); 184 } catch (ParserConfigurationException e) { 185 throw createException(e, CorextMessages.TypeInfoHistory_error_read); 186 } catch (IOException e) { 187 throw createException(e, CorextMessages.TypeInfoHistory_error_read); 188 } 189 190 if (root == null) return; 191 if (!root.getNodeName().equalsIgnoreCase(NODE_ROOT)) { 192 return; 193 } 194 NodeList list= root.getChildNodes(); 195 int length= list.getLength(); 196 for (int i= 0; i < length; ++i) { 197 Node node= list.item(i); 198 if (node.getNodeType() == Node.ELEMENT_NODE) { 199 Element type= (Element ) node; 200 if (type.getNodeName().equalsIgnoreCase(NODE_TYPE_INFO)) { 201 String name= type.getAttribute(NODE_NAME); 202 String pack= type.getAttribute(NODE_PACKAGE); 203 char[][] enclosingNames= getEnclosingNames(type); 204 String path= type.getAttribute(NODE_PATH); 205 int modifiers= 0; 206 try { 207 modifiers= Integer.parseInt(type.getAttribute(NODE_MODIFIERS)); 208 } catch (NumberFormatException e) { 209 } 211 TypeInfo info= factory.create( 212 pack.toCharArray(), name.toCharArray(), enclosingNames, modifiers, path); 213 fHistroy.put(info, info); 214 } 215 } 216 } 217 } 218 219 public synchronized void save() { 220 IPath stateLocation= JavaPlugin.getDefault().getStateLocation().append(FILENAME); 221 File file= new File (stateLocation.toOSString()); 222 OutputStream out= null; 223 try { 224 out= new FileOutputStream (file); 225 save(out); 226 } catch (IOException e) { 227 JavaPlugin.log(e); 228 } catch (CoreException e) { 229 JavaPlugin.log(e); 230 } finally { 231 try { 232 if (out != null) { 233 out.close(); 234 } 235 } catch (IOException e) { 236 JavaPlugin.log(e); 237 } 238 } 239 } 240 241 private void save(OutputStream stream) throws CoreException { 242 try { 243 DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance(); 244 DocumentBuilder builder= factory.newDocumentBuilder(); 245 Document document= builder.newDocument(); 246 247 Element rootElement = document.createElement(NODE_ROOT); 248 document.appendChild(rootElement); 249 250 Iterator values= fHistroy.values().iterator(); 251 while (values.hasNext()) { 252 TypeInfo type= (TypeInfo)values.next(); 253 Element typeElement= document.createElement(NODE_TYPE_INFO); 254 typeElement.setAttribute(NODE_NAME, type.getTypeName()); 255 typeElement.setAttribute(NODE_PACKAGE, type.getPackageName()); 256 typeElement.setAttribute(NODE_ENCLOSING_NAMES, type.getEnclosingName()); 257 typeElement.setAttribute(NODE_PATH, type.getPath()); 258 typeElement.setAttribute(NODE_MODIFIERS, Integer.toString(type.getModifiers())); 259 rootElement.appendChild(typeElement); 260 } 261 262 Transformer transformer=TransformerFactory.newInstance().newTransformer(); 263 transformer.setOutputProperty(OutputKeys.METHOD, "xml"); transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); DOMSource source = new DOMSource (document); 267 StreamResult result = new StreamResult (stream); 268 269 transformer.transform(source, result); 270 } catch (TransformerException e) { 271 throw createException(e, CorextMessages.TypeInfoHistory_error_serialize); 272 } catch (ParserConfigurationException e) { 273 throw createException(e, CorextMessages.TypeInfoHistory_error_serialize); 274 } 275 } 276 277 private char[][] getEnclosingNames(Element type) { 278 String enclosingNames= type.getAttribute(NODE_ENCLOSING_NAMES); 279 if (enclosingNames.length() == 0) 280 return EMPTY_ENCLOSING_NAMES; 281 StringTokenizer tokenizer= new StringTokenizer (enclosingNames, "."); List names= new ArrayList (); 283 while(tokenizer.hasMoreTokens()) { 284 String name= tokenizer.nextToken(); 285 names.add(name.toCharArray()); 286 } 287 return (char[][])names.toArray(new char[names.size()][]); 288 } 289 290 private static JavaUIException createException(Throwable t, String message) { 291 return new JavaUIException(JavaUIStatus.createError(IStatus.ERROR, message, t)); 292 } 293 } | Popular Tags |