KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > core > startup > InstalledFileLocatorImpl


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.netbeans.core.startup;
21
22 import java.io.File JavaDoc;
23 import java.util.ArrayList JavaDoc;
24 import java.util.Arrays JavaDoc;
25 import java.util.HashMap JavaDoc;
26 import java.util.HashSet JavaDoc;
27 import java.util.List JavaDoc;
28 import java.util.Map JavaDoc;
29 import java.util.Set JavaDoc;
30 import java.util.StringTokenizer JavaDoc;
31 import org.netbeans.Util;
32 import org.openide.filesystems.FileUtil;
33 import org.openide.modules.InstalledFileLocator;
34
35 /**
36  * Ability to locate NBM-installed files.
37  * Looks in ${netbeans.user} then each component of ${netbeans.dirs}
38  * and finally ${netbeans.home}.
39  * @author Jesse Glick
40  */

41 public final class InstalledFileLocatorImpl extends InstalledFileLocator {
42     
43     /** Default constructor for lookup. */
44     public InstalledFileLocatorImpl() {}
45     
46     private static final File JavaDoc[] dirs;
47     static {
48         List JavaDoc<File JavaDoc> _dirs = new ArrayList JavaDoc<File JavaDoc>();
49         addDir(_dirs, System.getProperty("netbeans.user"));
50         String JavaDoc nbdirs = System.getProperty("netbeans.dirs"); // #27151
51
if (nbdirs != null) {
52             StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc(nbdirs, File.pathSeparator);
53             while (tok.hasMoreTokens()) {
54                 addDir(_dirs, tok.nextToken());
55             }
56         }
57         addDir(_dirs, System.getProperty("netbeans.home"));
58         dirs = _dirs.toArray(new File JavaDoc[_dirs.size()]);
59     }
60     
61     private static void addDir(List JavaDoc<File JavaDoc> _dirs, String JavaDoc d) {
62         if (d != null) {
63             File JavaDoc f = new File JavaDoc(d).getAbsoluteFile();
64             if (f.isDirectory()) {
65                 _dirs.add(f);
66             }
67         }
68     }
69     
70     /**
71      * Cache of installed files (if present).
72      * Keys are directory prefixes, e.g. "" or "x/" or "x/y/" ('/' is sep).
73      * The values are nested maps; keys are entries in {@link #dirs}
74      * (not all entries need have keys, only those for which the dir exists),
75      * and values are unqualified file names which exist in that dir.
76      */

77     private static Map JavaDoc<String JavaDoc,Map JavaDoc<File JavaDoc,Set JavaDoc<String JavaDoc>>> fileCache = null;
78     
79     /**
80      * Called from <code>NonGui.run</code> early in the startup sequence to indicate
81      * that available files should be cached from now on. Should be matched by a call to
82      * {@link #discardCache} since the cache will be invalid if the user
83      * e.g. installs a new NBM without restarting.
84      */

85     public static synchronized void prepareCache() {
86         assert fileCache == null;
87         fileCache = new HashMap JavaDoc<String JavaDoc,Map JavaDoc<File JavaDoc,Set JavaDoc<String JavaDoc>>>();
88     }
89     
90     /**
91      * Called after startup is essentially complete.
92      * After this point, the list of files in the installation are not
93      * cached, since they might change due to dynamic NBM installation.
94      * Anyway the heaviest uses of {@link InstalledFileLocator} are
95      * during startup so that is when the cache has the most effect.
96      */

97     public static synchronized void discardCache() {
98         assert fileCache != null;
99         fileCache = null;
100     }
101     
102     /**
103      * Currently just searches user dir and install dir(s).
104      * @see "#28729 for a suggested better impl in AU"
105      */

106     public File JavaDoc locate(String JavaDoc relativePath, String JavaDoc codeNameBase, boolean localized) {
107         if (relativePath.length() == 0) {
108             throw new IllegalArgumentException JavaDoc("Cannot look up \"\" in InstalledFileLocator.locate"); // NOI18N
109
}
110         if (relativePath.charAt(0) == '/') {
111             throw new IllegalArgumentException JavaDoc("Paths passed to InstalledFileLocator.locate should not start with '/': " + relativePath); // NOI18N
112
}
113         int slashIdx = relativePath.lastIndexOf('/');
114         if (slashIdx == relativePath.length() - 1) {
115             throw new IllegalArgumentException JavaDoc("Paths passed to InstalledFileLocator.locate should not end in '/': " + relativePath); // NOI18N
116
}
117         
118         String JavaDoc prefix, name;
119         if (slashIdx != -1) {
120             prefix = relativePath.substring(0, slashIdx + 1);
121             name = relativePath.substring(slashIdx + 1);
122             assert name.length() > 0;
123         } else {
124             prefix = "";
125             name = relativePath;
126         }
127         synchronized (InstalledFileLocatorImpl.class) {
128             if (localized) {
129                 int i = name.lastIndexOf('.');
130                 String JavaDoc baseName, ext;
131                 if (i == -1) {
132                     baseName = name;
133                     ext = "";
134                 } else {
135                     baseName = name.substring(0, i);
136                     ext = name.substring(i);
137                 }
138                 String JavaDoc[] suffixes = org.netbeans.Util.getLocalizingSuffixesFast();
139                 for (int j = 0; j < suffixes.length; j++) {
140                     String JavaDoc locName = baseName + suffixes[j] + ext;
141                     File JavaDoc f = locateExactPath(prefix, locName);
142                     if (f != null) {
143                         return f;
144                     }
145                 }
146                 return null;
147             } else {
148                 return locateExactPath(prefix, name);
149             }
150         }
151     }
152     
153     /** Search all top dirs for a file. */
154     private static File JavaDoc locateExactPath(String JavaDoc prefix, String JavaDoc name) {
155         assert Thread.holdsLock(InstalledFileLocatorImpl.class);
156         if (fileCache != null) {
157             Map JavaDoc<File JavaDoc,Set JavaDoc<String JavaDoc>> fileCachePerPrefix = fileCache.get(prefix);
158             if (fileCachePerPrefix == null) {
159                 fileCachePerPrefix = new HashMap JavaDoc<File JavaDoc,Set JavaDoc<String JavaDoc>>(dirs.length * 2);
160                 for (int i = 0; i < dirs.length; i++) {
161                     File JavaDoc root = dirs[i];
162                     File JavaDoc d;
163                     if (prefix.length() > 0) {
164                         assert prefix.charAt(prefix.length() - 1) == '/';
165                         d = new File JavaDoc(root, prefix.substring(0, prefix.length() - 1).replace('/', File.separatorChar));
166                     } else {
167                         d = root;
168                     }
169                     if (d.isDirectory()) {
170                         String JavaDoc[] kids = d.list();
171                         if (kids != null) {
172                             fileCachePerPrefix.put(root, new HashSet JavaDoc<String JavaDoc>(Arrays.asList(kids)));
173                         } else {
174                             Util.err.warning("could not read files in " + d);
175                         }
176                     }
177                 }
178                 fileCache.put(prefix, fileCachePerPrefix);
179             }
180             for (int i = 0; i < dirs.length; i++) {
181                 Set JavaDoc<String JavaDoc> names = fileCachePerPrefix.get(dirs[i]);
182                 if (names != null && names.contains(name)) {
183                     return makeFile(dirs[i], prefix, name);
184                 }
185             }
186         } else {
187             for (int i = 0; i < dirs.length; i++) {
188                 File JavaDoc f = makeFile(dirs[i], prefix, name);
189                 if (f.exists()) {
190                     return f;
191                 }
192             }
193         }
194         return null;
195     }
196     
197     private static File JavaDoc makeFile(File JavaDoc dir, String JavaDoc prefix, String JavaDoc name) {
198         return FileUtil.normalizeFile(new File JavaDoc(dir, prefix.replace('/', File.separatorChar) + name));
199     }
200     
201 }
202
Popular Tags