KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > launching > sourcelookup > ArchiveSourceLocation


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.launching.sourcelookup;
12
13
14 import java.io.IOException JavaDoc;
15 import java.io.StringReader JavaDoc;
16 import com.ibm.icu.text.MessageFormat;
17 import java.util.Enumeration JavaDoc;
18 import java.util.HashMap JavaDoc;
19 import java.util.Iterator JavaDoc;
20 import java.util.zip.ZipEntry JavaDoc;
21 import java.util.zip.ZipFile JavaDoc;
22
23 import javax.xml.parsers.DocumentBuilder JavaDoc;
24 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
25 import javax.xml.parsers.ParserConfigurationException JavaDoc;
26 import javax.xml.transform.TransformerException JavaDoc;
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 JavaDoc;
38 import org.w3c.dom.Element JavaDoc;
39 import org.xml.sax.InputSource JavaDoc;
40 import org.xml.sax.SAXException JavaDoc;
41 import org.xml.sax.helpers.DefaultHandler JavaDoc;
42  
43 /**
44  * Locates source elements in an archive (zip) in the local file system. Returns
45  * instances of <code>ZipEntryStorage</code>.
46  * <p>
47  * This class may be instantiated; it is not intended to be subclassed.
48  * </p>
49  * @see IJavaSourceLocation
50  * @since 2.0
51  * @deprecated In 3.0, the debug platform provides source lookup facilities that
52  * should be used in place of the Java source lookup support provided in 2.0.
53  * The new facilities provide a source lookup director that coordinates source
54  * lookup among a set of participants, searching a set of source containers.
55  * See the following packages: <code>org.eclipse.debug.core.sourcelookup</code>
56  * and <code>org.eclipse.debug.core.sourcelookup.containers</code>. This class
57  * has been replaced by the following classes:
58  * <code>org.eclipse.debug.core.sourcelookup.containers.ArchiveSourceContainer</code>
59  * and <code>org.eclipse.debug.core.sourcelookup.containers.ExternalArchiveSourceContainer</code>.
60  */

61 public class ArchiveSourceLocation extends PlatformObject implements IJavaSourceLocation {
62     
63     /**
64      * Cache of shared zip files. Zip files are closed
65      * when the launching plug-in is shutdown.
66      */

67     private static HashMap JavaDoc fZipFileCache = new HashMap JavaDoc(5);
68
69     /**
70      * Returns a zip file with the given name
71      *
72      * @param name zip file name
73      * @return The zip file with the given name
74      * @exception IOException if unable to create the specified zip
75      * file
76      */

77     private static ZipFile JavaDoc getZipFile(String JavaDoc name) throws IOException JavaDoc {
78         synchronized (fZipFileCache) {
79             ZipFile JavaDoc zip = (ZipFile JavaDoc)fZipFileCache.get(name);
80             if (zip == null) {
81                 zip = new ZipFile JavaDoc(name);
82                 fZipFileCache.put(name, zip);
83             }
84             return zip;
85         }
86     }
87     
88     /**
89      * Closes all zip files that have been opened,
90      * and removes them from the zip file cache.
91      * This method is only to be called by the launching
92      * plug-in.
93      */

94     public static void closeArchives() {
95         synchronized (fZipFileCache) {
96             Iterator JavaDoc iter = fZipFileCache.values().iterator();
97             while (iter.hasNext()) {
98                 ZipFile JavaDoc file = (ZipFile JavaDoc)iter.next();
99                 synchronized (file) {
100                     try {
101                         file.close();
102                     } catch (IOException JavaDoc e) {
103                         LaunchingPlugin.log(e);
104                     }
105                 }
106             }
107             fZipFileCache.clear();
108         }
109     }
110     
111     /**
112      * The root source folder in the archive
113      */

114     private IPath fRootPath;
115     
116     /**
117      * Whether the root path has been detected (or set)
118      */

119     private boolean fRootDetected = false;
120     
121     /**
122      * The name of the archive
123      */

124     private String JavaDoc fName;
125
126     /**
127      * Constructs a new empty source location to be initialized with
128      * a memento.
129      */

130     public ArchiveSourceLocation() {
131     }
132         
133     /**
134      * Constructs a new source location that will retrieve source
135      * elements from the zip file with the given name.
136      *
137      * @param archiveName zip file
138      * @param sourceRoot a path to the root source folder in the
139      * specified archive, or <code>null</code> if the root source folder
140      * is the root of the archive
141      */

142     public ArchiveSourceLocation(String JavaDoc archiveName, String JavaDoc sourceRoot) {
143         super();
144         setName(archiveName);
145         setRootPath(sourceRoot);
146     }
147         
148     /* (non-Javadoc)
149      * @see org.eclipse.jdt.launching.sourcelookup.IJavaSourceLocation#findSourceElement(java.lang.String)
150      */

151     public Object JavaDoc findSourceElement(String JavaDoc name) throws CoreException {
152         try {
153             if (getArchive() == null) {
154                 return null;
155             }
156             
157             boolean possibleInnerType = false;
158             String JavaDoc pathStr= name.replace('.', '/');
159             int lastSlash = pathStr.lastIndexOf('/');
160             String JavaDoc typeName = pathStr;
161             do {
162                 IPath entryPath = new Path(typeName + ".java"); //$NON-NLS-1$
163
autoDetectRoot(entryPath);
164                 if (getRootPath() != null) {
165                     entryPath = getRootPath().append(entryPath);
166                 }
167                 ZipEntry JavaDoc 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 JavaDoc 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 JavaDoc[] {getName()}), e));
183         }
184     }
185     
186     /**
187      * Automatically detect the root path, if required.
188      *
189      * @param path source file name, excluding root path
190      * @throws CoreException if unable to detect the root path for this source archive
191      */

192     private void autoDetectRoot(IPath path) throws CoreException {
193         if (!fRootDetected) {
194             ZipFile JavaDoc zip = null;
195             try {
196                 zip = getArchive();
197             } catch (IOException JavaDoc 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 JavaDoc[] {getName()}), e));
200             }
201             synchronized (zip) {
202                 Enumeration JavaDoc entries = zip.entries();
203                 String JavaDoc fileName = path.toString();
204                 try {
205                     while (entries.hasMoreElements()) {
206                         ZipEntry JavaDoc entry = (ZipEntry JavaDoc)entries.nextElement();
207                         String JavaDoc entryName = entry.getName();
208                         if (entryName.endsWith(fileName)) {
209                             int rootLength = entryName.length() - fileName.length();
210                             if (rootLength > 0) {
211                                 String JavaDoc root = entryName.substring(0, rootLength);
212                                 setRootPath(root);
213                             }
214                             fRootDetected = true;
215                             return;
216                         }
217                     }
218                 } catch (IllegalStateException JavaDoc 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 JavaDoc[] {getName()}), e));
221                 }
222             }
223         }
224     }
225
226     /**
227      * Returns the archive associated with this source
228      * location.
229      *
230      * @return zip file
231      * @throws IOException if unable to create the zip
232      * file associated with this location
233      */

234     protected ZipFile JavaDoc getArchive() throws IOException JavaDoc {
235         return getZipFile(getName());
236     }
237     
238     /**
239      * Sets the location of the root source folder within
240      * the archive, or <code>null</code> if the root source
241      * folder is the root of the archive
242      *
243      * @param path the location of the root source folder within
244      * the archive, or <code>null</code> if the root source
245      * folder is the root of the archive
246      */

247     private void setRootPath(String JavaDoc 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     /**
257      * Returns the location of the root source folder within
258      * the archive, or <code>null</code> if the root source
259      * folder is the root of the archive
260      *
261      * @return the location of the root source folder within
262      * the archive, or <code>null</code> if the root source
263      * folder is the root of the archive
264      */

265     public IPath getRootPath() {
266         return fRootPath;
267     }
268     
269     /**
270      * Returns the name of the archive associated with this
271      * source location
272      *
273      * @return the name of the archive associated with this
274      * source location
275      */

276     public String JavaDoc getName() {
277         return fName;
278     }
279     
280     /**
281      * Sets the name of the archive associated with this
282      * source location
283      *
284      * @param name the name of the archive associated with this
285      * source location
286      */

287     private void setName(String JavaDoc name) {
288         fName = name;
289     }
290     
291     /* (non-Javadoc)
292      * @see java.lang.Object#equals(java.lang.Object)
293      */

294     public boolean equals(Object JavaDoc object) {
295         return object instanceof ArchiveSourceLocation &&
296              getName().equals(((ArchiveSourceLocation)object).getName());
297     }
298     
299     /* (non-Javadoc)
300      * @see java.lang.Object#hashCode()
301      */

302     public int hashCode() {
303         return getName().hashCode();
304     }
305     
306     /* (non-Javadoc)
307      * @see org.eclipse.jdt.launching.sourcelookup.IJavaSourceLocation#getMemento()
308      */

309     public String JavaDoc getMemento() throws CoreException {
310         try {
311             Document JavaDoc doc = LaunchingPlugin.getDocument();
312             Element JavaDoc node = doc.createElement("archiveSourceLocation"); //$NON-NLS-1$
313
doc.appendChild(node);
314             node.setAttribute("archivePath", getName()); //$NON-NLS-1$
315
if (getRootPath() != null) {
316                 node.setAttribute("rootPath", getRootPath().toString()); //$NON-NLS-1$
317
}
318         
319             return LaunchingPlugin.serializeDocument(doc);
320         } catch (IOException JavaDoc e) {
321             abort(MessageFormat.format(LaunchingMessages.ArchiveSourceLocation_Unable_to_create_memento_for_archive_source_location__0__1, new String JavaDoc[] {getName()}), e);
322         } catch (ParserConfigurationException JavaDoc e) {
323             abort(MessageFormat.format(LaunchingMessages.ArchiveSourceLocation_Unable_to_create_memento_for_archive_source_location__0__1, new String JavaDoc[] {getName()}), e);
324         } catch (TransformerException JavaDoc e) {
325             abort(MessageFormat.format(LaunchingMessages.ArchiveSourceLocation_Unable_to_create_memento_for_archive_source_location__0__1, new String JavaDoc[] {getName()}), e);
326         }
327         // execution will not reach here
328
return null;
329     }
330
331     /* (non-Javadoc)
332      * @see org.eclipse.jdt.launching.sourcelookup.IJavaSourceLocation#initializeFrom(java.lang.String)
333      */

334     public void initializeFrom(String JavaDoc memento) throws CoreException {
335         Exception JavaDoc ex = null;
336         try {
337             Element JavaDoc root = null;
338             DocumentBuilder JavaDoc parser =
339                 DocumentBuilderFactory.newInstance().newDocumentBuilder();
340             parser.setErrorHandler(new DefaultHandler JavaDoc());
341             StringReader JavaDoc reader = new StringReader JavaDoc(memento);
342             InputSource JavaDoc source = new InputSource JavaDoc(reader);
343             root = parser.parse(source).getDocumentElement();
344                                                 
345             String JavaDoc path = root.getAttribute("archivePath"); //$NON-NLS-1$
346
if (isEmpty(path)) {
347                 abort(LaunchingMessages.ArchiveSourceLocation_Unable_to_initialize_source_location___missing_archive_path__3, null);
348             }
349             String JavaDoc rootPath = root.getAttribute("rootPath"); //$NON-NLS-1$
350

351             setName(path);
352             setRootPath(rootPath);
353             return;
354         } catch (ParserConfigurationException JavaDoc e) {
355             ex = e;
356         } catch (SAXException JavaDoc e) {
357             ex = e;
358         } catch (IOException JavaDoc e) {
359             ex = e;
360         }
361         abort(LaunchingMessages.ArchiveSourceLocation_Exception_occurred_initializing_source_location__5, ex);
362     }
363
364     private boolean isEmpty(String JavaDoc string) {
365         return string == null || string.length() == 0;
366     }
367     
368     /*
369      * Throws an internal error exception
370      */

371     private void abort(String JavaDoc message, Throwable JavaDoc 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