1 11 package org.eclipse.jdt.launching.sourcelookup; 12 13 14 import java.io.IOException ; 15 import java.io.StringReader ; 16 import com.ibm.icu.text.MessageFormat; 17 import java.util.Enumeration ; 18 import java.util.HashMap ; 19 import java.util.Iterator ; 20 import java.util.zip.ZipEntry ; 21 import java.util.zip.ZipFile ; 22 23 import javax.xml.parsers.DocumentBuilder ; 24 import javax.xml.parsers.DocumentBuilderFactory ; 25 import javax.xml.parsers.ParserConfigurationException ; 26 import javax.xml.transform.TransformerException ; 27 28 import org.eclipse.core.runtime.CoreException; 29 import org.eclipse.core.runtime.IPath; 30 import org.eclipse.core.runtime.IStatus; 31 import org.eclipse.core.runtime.Path; 32 import org.eclipse.core.runtime.PlatformObject; 33 import org.eclipse.core.runtime.Status; 34 import org.eclipse.jdt.internal.launching.LaunchingMessages; 35 import org.eclipse.jdt.internal.launching.LaunchingPlugin; 36 import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; 37 import org.w3c.dom.Document ; 38 import org.w3c.dom.Element ; 39 import org.xml.sax.InputSource ; 40 import org.xml.sax.SAXException ; 41 import org.xml.sax.helpers.DefaultHandler ; 42 43 61 public class ArchiveSourceLocation extends PlatformObject implements IJavaSourceLocation { 62 63 67 private static HashMap fZipFileCache = new HashMap (5); 68 69 77 private static ZipFile getZipFile(String name) throws IOException { 78 synchronized (fZipFileCache) { 79 ZipFile zip = (ZipFile )fZipFileCache.get(name); 80 if (zip == null) { 81 zip = new ZipFile (name); 82 fZipFileCache.put(name, zip); 83 } 84 return zip; 85 } 86 } 87 88 94 public static void closeArchives() { 95 synchronized (fZipFileCache) { 96 Iterator iter = fZipFileCache.values().iterator(); 97 while (iter.hasNext()) { 98 ZipFile file = (ZipFile )iter.next(); 99 synchronized (file) { 100 try { 101 file.close(); 102 } catch (IOException e) { 103 LaunchingPlugin.log(e); 104 } 105 } 106 } 107 fZipFileCache.clear(); 108 } 109 } 110 111 114 private IPath fRootPath; 115 116 119 private boolean fRootDetected = false; 120 121 124 private String fName; 125 126 130 public ArchiveSourceLocation() { 131 } 132 133 142 public ArchiveSourceLocation(String archiveName, String sourceRoot) { 143 super(); 144 setName(archiveName); 145 setRootPath(sourceRoot); 146 } 147 148 151 public Object findSourceElement(String name) throws CoreException { 152 try { 153 if (getArchive() == null) { 154 return null; 155 } 156 157 boolean possibleInnerType = false; 158 String pathStr= name.replace('.', '/'); 159 int lastSlash = pathStr.lastIndexOf('/'); 160 String typeName = pathStr; 161 do { 162 IPath entryPath = new Path(typeName + ".java"); autoDetectRoot(entryPath); 164 if (getRootPath() != null) { 165 entryPath = getRootPath().append(entryPath); 166 } 167 ZipEntry entry = getArchive().getEntry(entryPath.toString()); 168 if (entry != null) { 169 return new ZipEntryStorage(getArchive(), entry); 170 } 171 int index = typeName.lastIndexOf('$'); 172 if (index > lastSlash) { 173 typeName = typeName.substring(0, index); 174 possibleInnerType = true; 175 } else { 176 possibleInnerType = false; 177 } 178 } while (possibleInnerType); 179 return null; 180 } catch (IOException e) { 181 throw new CoreException(new Status(IStatus.ERROR, LaunchingPlugin.getUniqueIdentifier(), IJavaLaunchConfigurationConstants.ERR_INTERNAL_ERROR, 182 MessageFormat.format(LaunchingMessages.ArchiveSourceLocation_Unable_to_locate_source_element_in_archive__0__1, new String [] {getName()}), e)); 183 } 184 } 185 186 192 private void autoDetectRoot(IPath path) throws CoreException { 193 if (!fRootDetected) { 194 ZipFile zip = null; 195 try { 196 zip = getArchive(); 197 } catch (IOException e) { 198 throw new CoreException(new Status(IStatus.ERROR, LaunchingPlugin.getUniqueIdentifier(), IJavaLaunchConfigurationConstants.ERR_INTERNAL_ERROR, 199 MessageFormat.format(LaunchingMessages.ArchiveSourceLocation_Exception_occurred_while_detecting_root_source_directory_in_archive__0__1, new String [] {getName()}), e)); 200 } 201 synchronized (zip) { 202 Enumeration entries = zip.entries(); 203 String fileName = path.toString(); 204 try { 205 while (entries.hasMoreElements()) { 206 ZipEntry entry = (ZipEntry )entries.nextElement(); 207 String entryName = entry.getName(); 208 if (entryName.endsWith(fileName)) { 209 int rootLength = entryName.length() - fileName.length(); 210 if (rootLength > 0) { 211 String root = entryName.substring(0, rootLength); 212 setRootPath(root); 213 } 214 fRootDetected = true; 215 return; 216 } 217 } 218 } catch (IllegalStateException e) { 219 throw new CoreException(new Status(IStatus.ERROR, LaunchingPlugin.getUniqueIdentifier(), IJavaLaunchConfigurationConstants.ERR_INTERNAL_ERROR, 220 MessageFormat.format(LaunchingMessages.ArchiveSourceLocation_Exception_occurred_while_detecting_root_source_directory_in_archive__0__2, new String [] {getName()}), e)); 221 } 222 } 223 } 224 } 225 226 234 protected ZipFile getArchive() throws IOException { 235 return getZipFile(getName()); 236 } 237 238 247 private void setRootPath(String path) { 248 if (path == null || path.trim().length() == 0) { 249 fRootPath = null; 250 } else { 251 fRootPath = new Path(path); 252 fRootDetected = true; 253 } 254 } 255 256 265 public IPath getRootPath() { 266 return fRootPath; 267 } 268 269 276 public String getName() { 277 return fName; 278 } 279 280 287 private void setName(String name) { 288 fName = name; 289 } 290 291 294 public boolean equals(Object object) { 295 return object instanceof ArchiveSourceLocation && 296 getName().equals(((ArchiveSourceLocation)object).getName()); 297 } 298 299 302 public int hashCode() { 303 return getName().hashCode(); 304 } 305 306 309 public String getMemento() throws CoreException { 310 try { 311 Document doc = LaunchingPlugin.getDocument(); 312 Element node = doc.createElement("archiveSourceLocation"); doc.appendChild(node); 314 node.setAttribute("archivePath", getName()); if (getRootPath() != null) { 316 node.setAttribute("rootPath", getRootPath().toString()); } 318 319 return LaunchingPlugin.serializeDocument(doc); 320 } catch (IOException e) { 321 abort(MessageFormat.format(LaunchingMessages.ArchiveSourceLocation_Unable_to_create_memento_for_archive_source_location__0__1, new String [] {getName()}), e); 322 } catch (ParserConfigurationException e) { 323 abort(MessageFormat.format(LaunchingMessages.ArchiveSourceLocation_Unable_to_create_memento_for_archive_source_location__0__1, new String [] {getName()}), e); 324 } catch (TransformerException e) { 325 abort(MessageFormat.format(LaunchingMessages.ArchiveSourceLocation_Unable_to_create_memento_for_archive_source_location__0__1, new String [] {getName()}), e); 326 } 327 return null; 329 } 330 331 334 public void initializeFrom(String memento) throws CoreException { 335 Exception ex = null; 336 try { 337 Element root = null; 338 DocumentBuilder parser = 339 DocumentBuilderFactory.newInstance().newDocumentBuilder(); 340 parser.setErrorHandler(new DefaultHandler ()); 341 StringReader reader = new StringReader (memento); 342 InputSource source = new InputSource (reader); 343 root = parser.parse(source).getDocumentElement(); 344 345 String path = root.getAttribute("archivePath"); if (isEmpty(path)) { 347 abort(LaunchingMessages.ArchiveSourceLocation_Unable_to_initialize_source_location___missing_archive_path__3, null); 348 } 349 String rootPath = root.getAttribute("rootPath"); 351 setName(path); 352 setRootPath(rootPath); 353 return; 354 } catch (ParserConfigurationException e) { 355 ex = e; 356 } catch (SAXException e) { 357 ex = e; 358 } catch (IOException e) { 359 ex = e; 360 } 361 abort(LaunchingMessages.ArchiveSourceLocation_Exception_occurred_initializing_source_location__5, ex); 362 } 363 364 private boolean isEmpty(String string) { 365 return string == null || string.length() == 0; 366 } 367 368 371 private void abort(String message, Throwable e) throws CoreException { 372 IStatus s = new Status(IStatus.ERROR, LaunchingPlugin.getUniqueIdentifier(), IJavaLaunchConfigurationConstants.ERR_INTERNAL_ERROR, message, e); 373 throw new CoreException(s); 374 } 375 } 376 | Popular Tags |