KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openide > modules > InstalledFileLocator


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.openide.modules;
21
22 import java.io.File JavaDoc;
23 import java.util.Collection JavaDoc;
24 import org.openide.util.Lookup;
25 import org.openide.util.LookupEvent;
26 import org.openide.util.LookupListener;
27
28 /**
29  * Service providing the ability to locate a module-installed file in
30  * the NetBeans application's installation.
31  * Zero or more instances may be registered to lookup.
32  * @author Jesse Glick
33  * @since 3.21
34  * @see <a HREF="http://www.netbeans.org/issues/show_bug.cgi?id=28683">Issue #28683</a>
35  */

36 public abstract class InstalledFileLocator {
37     private static final InstalledFileLocator DEFAULT = new InstalledFileLocator() {
38         public File JavaDoc locate(String JavaDoc rp, String JavaDoc cnb, boolean l) {
39             InstalledFileLocator[] ifls = getInstances();
40             
41             for (int i = 0; i < ifls.length; i++) {
42                 File JavaDoc f = ifls[i].locate(rp, cnb, l);
43                 
44                 if (f != null) {
45                     return f;
46                 }
47             }
48             
49             return null;
50         }
51     };
52     
53     private static InstalledFileLocator[] instances = null;
54     private static Lookup.Result<InstalledFileLocator> result = null;
55     /**
56      * Used just for guarding direct access to {@link #instances} and {@link #result}.
57      * Should not call foreign code while holding this.
58      * Cf. comments in #64710.
59      */

60     private static final Object JavaDoc LOCK = new String JavaDoc(InstalledFileLocator.class.getName());
61     
62     /**
63      * No-op constructor for use by subclasses.
64      */

65     protected InstalledFileLocator() {
66     }
67     
68     /**
69      * Try to locate a file.
70      * <div class="nonnormative">
71      * <p>
72      * When using the normal NetBeans installation structure and NBM file format,
73      * this path will be relative to the installation directory (or user directory,
74      * for a locally installed module). Other possible installation mechanisms, such
75      * as JNLP (Java WebStart), might arrange the physical files differently, but
76      * generally the path indicated by a module's normal NBM file (beneath <samp>netbeans/</samp>
77      * in the NBM) should be interpreted by the locator implementation to point to the actual
78      * location of the file, so the module need not be aware of such details. Some
79      * locator implementations may perform the search more accurately or quickly
80      * when given a code name base for the module that supplies the file.
81      * </p>
82      * <p>
83      * The file may refer to a directory (no trailing slash!), in which case the locator
84      * should attempt to find that directory in the installation. Note that only one
85      * file may be located from a given path, so generally this method will not be
86      * useful where a directory can contain many items that may be merged between e.g.
87      * the installation and user directories. For example, the <samp>docs</samp> folder
88      * (used e.g. for Javadoc) might contain several ZIP files in both the installation and
89      * user areas. There is currently no supported way to enumerate all such files. Therefore
90      * searching for a directory should be attempted only when there is just one module which
91      * is expected to provide that directory and all of its contents. The module may assume
92      * that all contained files are in the same relative structure in the directory as in
93      * the normal NBM-based installation; unusual locator implementations may need to create
94      * temporary directories with matching structures to return from this method, in case the
95      * physical file locations are not in such a directory structure.
96      * See issue #36701 for details.
97      * </p>
98      * </div>
99      * <p>
100      * Localized and branded lookups should follow the normal naming conventions,
101      * e.g. <samp>docs/OpenAPIs_ja.zip</samp> would be used for Japanese Javadoc
102      * and <samp>locate("docs/OpenAPIs.zip",&nbsp;&#8230;,&nbsp;true)</samp>
103      * would find it when running in Japanese locale.
104      * </p>
105      * <div class="nonnormative">
106      * <p>
107      * For cases where the search is for a module JAR or one of its extensions, client
108      * code may prefer to use the code source given by a class loader. This will permit
109      * a client to find the base URL (may or may not refer to a file) responsible for loading
110      * the contents of the protection domain, typically a JAR file, containing a class
111      * which is accessible to the module class loader. For example:
112      * </p>
113      * <pre>
114      <span class="type">Class</span> <span class="variable-name">c</span> = ClassMyModuleDefines.<span class="keyword">class</span>;
115      <span class="type">URL</span> <span class="variable-name">u</span> = c.getProtectionDomain().getCodeSource().getLocation();
116      * </pre>
117      * <p>
118      * When running from a JAR file, this will typically give e.g.
119      * <samp>file:/path/to/archive.jar</samp>. This information may be useful,
120      * but it is not conclusive, since there is no guarantee what the URL protocol
121      * will be, nor that the returned URL uniquely identifies a JAR shipped with
122      * the module in its canonical NBM format. <code>InstalledFileLocator</code>
123      * provides stronger guarantees than this technique, since you can explicitly
124      * name a JAR file to be located on disk.
125      * </p>
126      * </div>
127      * <div class="nonnormative">
128      * <p>
129      * This class should <em>not</em> be used just to find resources on the system
130      * filesystem, which in the normal NetBeans installation structure means the
131      * result of merging <samp>${netbeans.home}/system/</samp> with <samp>${netbeans.user}/system/</samp>
132      * as well as module layers and perhaps project-specific storage. To find data in
133      * the system filesystem, use the Filesystems API, e.g. in your layer you can predefine:
134      * </p>
135      <pre>
136      &lt;<span class="function-name">filesystem</span>&gt;
137      &lt;<span class="function-name">folder</span> <span class="variable-name">name</span>=<span class="string">"MyModule"</span>&gt;
138      &lt;<span class="function-name">file</span> <span class="variable-name">name</span>=<span class="string">"data.xml"</span> <span class="variable-name">url</span>=<span class="string">"contents-in-module-jar.xml"</span>/&gt;
139      &lt;/<span class="function-name">folder</span>&gt;
140      &lt;/<span class="function-name">filesystem</span>&gt;
141      </pre>
142      * <p>
143      * Then in your code use:
144      * </p>
145      <pre>
146      <span class="type">String</span> <span class="variable-name">path</span> = <span class="string">"MyModule/data.xml"</span>;
147      <span class="type">FileSystem</span> <span class="variable-name">sfs</span> = Repository.getDefault().getDefaultFileSystem();
148      <span class="type">FileObject</span> <span class="variable-name">fo</span> = sfs.findResource(path);
149      <span class="keyword">if</span> (fo != <span class="constant">null</span>) {
150      <span class="comment">// use fo.getInputStream() etc.
151      </span> <span class="comment">// FileUtil.toFile(fo) will often be null, do not rely on it!
152      </span>}
153      </pre>
154      * </div>
155      * @param relativePath path from install root, e.g. <samp>docs/OpenAPIs.zip</samp>
156      * or <samp>modules/ext/somelib.jar</samp>
157      * (always using <samp>/</samp> as a separator, regardless of platform)
158      * @param codeNameBase name of the supplying module, e.g. <samp>org.netbeans.modules.foo</samp>;
159      * may be <code>null</code> if unknown
160      * @param localized true to perform a localized and branded lookup (useful for documentation etc.)
161      * @return the requested <code>File</code>, if it can be found, else <code>null</code>
162      */

163     public abstract File JavaDoc locate(String JavaDoc relativePath, String JavaDoc codeNameBase, boolean localized);
164     
165     /**
166      * Get a master locator.
167      * Lookup is searched for all registered locators.
168      * They are merged together and called in sequence
169      * until one of them is able to service a request.
170      * If you use this call, require the token <code>org.openide.modules.InstalledFileLocator</code>
171      * to require any autoload modules which can provide locators.
172      * @return a master merging locator (never null)
173      */

174     public static InstalledFileLocator getDefault() {
175         return DEFAULT;
176     }
177     
178     private static InstalledFileLocator[] getInstances() {
179         synchronized (LOCK) {
180             if (instances != null) {
181                 return instances;
182             }
183         }
184         
185         Lookup.Result<InstalledFileLocator> _result;
186         synchronized (LOCK) {
187             _result = result;
188         }
189         if (_result == null) {
190             _result = Lookup.getDefault().lookupResult(InstalledFileLocator.class);
191             _result.addLookupListener(new LookupListener() {
192                 public void resultChanged(LookupEvent e) {
193                     synchronized (LOCK) {
194                         instances = null;
195                     }
196                 }
197             });
198             synchronized (LOCK) {
199                 result = _result;
200             }
201         }
202         
203         Collection JavaDoc<? extends InstalledFileLocator> c = _result.allInstances();
204         synchronized (LOCK) {
205             return instances = c.toArray(new InstalledFileLocator[c.size()]);
206         }
207     }
208     
209 }
210
Popular Tags