KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > api > project > FileOwnerQuery


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.api.project;
21
22 import java.io.File JavaDoc;
23 import java.net.MalformedURLException JavaDoc;
24 import java.net.URI JavaDoc;
25 import java.net.URISyntaxException JavaDoc;
26 import java.net.URL JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.util.List JavaDoc;
29 import org.netbeans.modules.projectapi.SimpleFileOwnerQueryImplementation;
30 import org.netbeans.spi.project.FileOwnerQueryImplementation;
31 import org.openide.filesystems.FileObject;
32 import org.openide.filesystems.FileUtil;
33 import org.openide.util.Lookup;
34 import org.openide.util.LookupEvent;
35 import org.openide.util.LookupListener;
36
37 /**
38  * Find the project which owns a file.
39  * <p>
40  * There is a default implementation of {@link org.netbeans.spi.project.FileOwnerQueryImplementation}
41  * which considers a file owned by the project corresponding to the nearest enclosing
42  * project directory or marked external owner, if such a directory exists. But
43  * other implementations can be registered to lookup as well.
44  * <p>
45  * Warning: This class and it's methods may not be used within DataObject recognition in DataLoaders.
46  * eg. in {@link org.openide.loaders.MultiFileLoader#findPrimaryFile}
47  *
48  * @author Jesse Glick
49  */

50 public class FileOwnerQuery {
51     
52     // XXX acquire the appropriate ProjectManager.mutex for the duration of calls
53

54     private static Lookup.Result<FileOwnerQueryImplementation> implementations;
55
56     /** Cache of all available FileOwnerQueryImplementation instances. */
57     private static List JavaDoc<FileOwnerQueryImplementation> cache;
58     
59     private FileOwnerQuery() {}
60
61     /**
62      * Find the project, if any, which "owns" the given file.
63      * @param file the file (generally on disk)
64      * @return a project which contains it, or null if there is no known project containing it
65      */

66     public static Project getOwner(FileObject file) {
67         if (file == null) {
68             throw new NullPointerException JavaDoc("Passed null to FileOwnerQuery.getOwner(FileObject)"); // NOI18N
69
}
70         FileObject archiveRoot = FileUtil.getArchiveFile(file);
71         if (archiveRoot != null) {
72             file = archiveRoot;
73         }
74         for (FileOwnerQueryImplementation q : getInstances()) {
75             Project p = q.getOwner(file);
76             if (p != null) {
77                 return p;
78             }
79         }
80         return null;
81     }
82
83     /**
84      * Find the project, if any, which "owns" the given URI.
85      * @param uri the uri to the file (generally on disk); must be absolute and not opaque
86      * @return a project which contains it, or null if there is no known project containing it
87      * @throws IllegalArgumentException if the URI is relative or opaque
88      */

89     public static Project getOwner(URI JavaDoc uri) {
90         if (uri.isOpaque() && "jar".equalsIgnoreCase(uri.getScheme())) { //NOI18N
91
// XXX the following is bogus; should use FileUtil methods
92
String JavaDoc schemaPart = uri.getSchemeSpecificPart();
93             int index = schemaPart.lastIndexOf ('!'); //NOI18N
94
if (index>0) {
95                 schemaPart = schemaPart.substring(0,index);
96             }
97             // XXX: schemaPart can contains spaces. create File first and
98
// then convert it to URI.
99
try {
100                 //#85137 - # character in uri path seems to cause problems, because it's not escaped. test added.
101
schemaPart = schemaPart.replace("#", "%23");
102                 uri = new URI JavaDoc(schemaPart);
103             } catch (URISyntaxException JavaDoc ex) {
104                 try {
105                     URL JavaDoc u = new URL JavaDoc(schemaPart);
106                     // XXX bad to ever use new File(URL.getPath()):
107
uri = new File JavaDoc(u.getPath()).toURI();
108                 } catch (MalformedURLException JavaDoc ex2) {
109                     ex2.printStackTrace();
110                     assert false : schemaPart;
111                     return null;
112                 }
113             }
114         }
115         else if (!uri.isAbsolute() || uri.isOpaque()) {
116             throw new IllegalArgumentException JavaDoc("Bad URI: " + uri); // NOI18N
117
}
118         for (FileOwnerQueryImplementation q : getInstances()) {
119             Project p = q.getOwner(uri);
120             if (p != null) {
121                 return p;
122             }
123         }
124         return null;
125     }
126     
127     /**
128      * Intended for use from unit tests. Clears internal state such as
129      * external file owners.
130      */

131     static void reset() {
132         SimpleFileOwnerQueryImplementation.reset();
133     }
134     
135     /**
136      * Simplest algorithm for marking external file owners, which just keeps
137      * a transient memory cache of this information.
138      * The external marking is only guaranteed to be good during this VM session
139      * for as long as the external file root is retained in memory as a
140      * <code>FileObject</code>. For this reason, a project which makes such a
141      * marking when it is created is obliged to hold a reference to the external
142      * file root for as long as the project itself is in memory, to ensure that
143      * it continues to work.
144      */

145     public static final int EXTERNAL_ALGORITHM_TRANSIENT = 0;
146     
147     /**
148      * Mark an external folder or file as being owned by a particular project.
149      * After this call is made, for the duration appropriate to the selected
150      * algorithm, that folder or file and its ancestors will be considered owned
151      * by the project (if any) matching the named project directory, except in
152      * the case that a lower enclosing project directory can be found.
153      * <p class="nonnormative">
154      * Typical usage would be to call this method for each external source root
155      * of a project (if any) as soon as the project is loaded, if a transient
156      * algorithm is selected, or only when the project is created, if a reliable
157      * persistent algorithm is selected.
158      * </p>
159      * @param root a folder or a file which should be considered part of a project
160      * @param owner a project which should be considered to own that folder tree
161      * (any prior marked external owner is overridden),
162      * or null to cancel external ownership for this folder root
163      * @param algorithm an algorithm to use for retaining this information;
164      * currently may only be {@link #EXTERNAL_ALGORITHM_TRANSIENT}
165      * @throws IllegalArgumentException if the root or owner is null, if an unsupported
166      * algorithm is requested,
167      * if the root is already a project directory,
168      * or if the root is already equal to or inside the owner's
169      * project directory (it may however be an ancestor)
170      * @see <a HREF="@org-netbeans-modules-project-ant@/org/netbeans/spi/project/support/ant/SourcesHelper.html"><code>SourcesHelper</code></a>
171      */

172     public static void markExternalOwner(FileObject root, Project owner, int algorithm) throws IllegalArgumentException JavaDoc {
173         switch (algorithm) {
174         case EXTERNAL_ALGORITHM_TRANSIENT:
175             // XXX check args
176
SimpleFileOwnerQueryImplementation.markExternalOwnerTransient(root, owner);
177             break;
178         default:
179             throw new IllegalArgumentException JavaDoc("No such algorithm: " + algorithm); // NOI18N
180
}
181     }
182     
183     /**
184      * Mark an external URI (folder or file) as being owned by a particular project.
185      * After this call is made, for the duration appropriate to the selected
186      * algorithm, that folder or file and its ancestors will be considered owned
187      * by the project (if any) matching the named project directory, except in
188      * the case that a lower enclosing project directory can be found.
189      * <p class="nonnormative">
190      * Typical usage would be to call this method for each external source root
191      * of a project (if any) as soon as the project is loaded, if a transient
192      * algorithm is selected, or only when the project is created, if a reliable
193      * persistent algorithm is selected.
194      * </p>
195      * @param root an URI of a folder or a file which should be considered part of a project
196      * @param owner a project which should be considered to own that folder tree
197      * (any prior marked external owner is overridden),
198      * or null to cancel external ownership for this folder root
199      * @param algorithm an algorithm to use for retaining this information;
200      * currently may only be {@link #EXTERNAL_ALGORITHM_TRANSIENT}
201      * @throws IllegalArgumentException if the root or owner is null, if an unsupported
202      * algorithm is requested,
203      * if the root is already a project directory,
204      * or if the root is already equal to or inside the owner's
205      * project directory (it may however be an ancestor)
206      * @see <a HREF="@org-netbeans-modules-project-ant@/org/netbeans/spi/project/support/ant/SourcesHelper.html"><code>SourcesHelper</code></a>
207      */

208     public static void markExternalOwner(URI JavaDoc root, Project owner, int algorithm) throws IllegalArgumentException JavaDoc {
209         switch (algorithm) {
210         case EXTERNAL_ALGORITHM_TRANSIENT:
211             // XXX check args
212
SimpleFileOwnerQueryImplementation.markExternalOwnerTransient(root, owner);
213             break;
214         default:
215             throw new IllegalArgumentException JavaDoc("No such algorithm: " + algorithm); // NOI18N
216
}
217     }
218     
219     /* TBD whether this is necessary:
220     public static FileObject getMarkedExternalOwner(FileObject root) {}
221      */

222
223     private static synchronized List JavaDoc<FileOwnerQueryImplementation> getInstances() {
224         if (implementations == null) {
225             implementations = Lookup.getDefault().lookupResult(FileOwnerQueryImplementation.class);
226             implementations.addLookupListener(new LookupListener() {
227                 public void resultChanged (LookupEvent ev) {
228                     synchronized (FileOwnerQuery.class) {
229                         cache = null;
230                     }
231                 }});
232         }
233         if (cache == null) {
234             cache = new ArrayList JavaDoc<FileOwnerQueryImplementation>(implementations.allInstances());
235         }
236         return cache;
237     }
238     
239 }
240
Popular Tags