KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > java > project > BrokenReferencesModel


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.modules.java.project;
21
22 import java.io.File JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.net.URL JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.HashSet JavaDoc;
27 import java.util.Iterator JavaDoc;
28 import java.util.LinkedHashSet JavaDoc;
29 import java.util.List JavaDoc;
30 import java.util.Map JavaDoc;
31 import java.util.Set JavaDoc;
32 import java.util.regex.Matcher JavaDoc;
33 import java.util.regex.Pattern JavaDoc;
34 import javax.swing.AbstractListModel JavaDoc;
35 import org.netbeans.api.java.platform.JavaPlatform;
36 import org.netbeans.api.java.platform.JavaPlatformManager;
37 import org.netbeans.api.project.Project;
38 import org.netbeans.api.project.ProjectManager;
39 import org.netbeans.api.project.libraries.Library;
40 import org.netbeans.api.project.libraries.LibraryManager;
41 import org.netbeans.api.queries.CollocationQuery;
42 import org.netbeans.spi.project.support.ant.AntProjectHelper;
43 import org.netbeans.spi.project.support.ant.EditableProperties;
44 import org.netbeans.spi.project.support.ant.PropertyEvaluator;
45 import org.netbeans.spi.project.support.ant.PropertyUtils;
46 import org.netbeans.spi.project.support.ant.ReferenceHelper;
47 import org.openide.ErrorManager;
48 import org.openide.filesystems.FileObject;
49 import org.openide.filesystems.FileUtil;
50 import org.openide.filesystems.URLMapper;
51 import org.openide.util.NbBundle;
52
53 public class BrokenReferencesModel extends AbstractListModel JavaDoc {
54
55     private String JavaDoc[] props;
56     private String JavaDoc[] platformsProps;
57     private AntProjectHelper helper;
58     private ReferenceHelper resolver;
59     private List JavaDoc<OneReference> references;
60
61     public BrokenReferencesModel(AntProjectHelper helper,
62             ReferenceHelper resolver, String JavaDoc[] props, String JavaDoc[] platformsProps) {
63         this.props = props;
64         this.platformsProps = platformsProps;
65         this.resolver = resolver;
66         this.helper = helper;
67         references = new ArrayList JavaDoc<OneReference>();
68         refresh();
69     }
70     
71     public void refresh() {
72         Set JavaDoc<OneReference> all = new LinkedHashSet JavaDoc<OneReference>();
73         Set JavaDoc<OneReference> s = getReferences(helper, helper.getStandardPropertyEvaluator(), props, false);
74         all.addAll(s);
75         s = getPlatforms(helper.getStandardPropertyEvaluator(), platformsProps, false);
76         all.addAll(s);
77         updateReferencesList(references, all);
78         this.fireContentsChanged(this, 0, getSize());
79     }
80
81     public Object JavaDoc getElementAt(int index) {
82         OneReference or = getOneReference(index);
83         String JavaDoc bundleID;
84         switch (or.type) {
85             case REF_TYPE_LIBRARY:
86             case REF_TYPE_LIBRARY_CONTENT:
87                 bundleID = "LBL_BrokenLinksCustomizer_BrokenLibrary"; // NOI18N
88
break;
89             case REF_TYPE_PROJECT:
90                 bundleID = "LBL_BrokenLinksCustomizer_BrokenProjectReference"; // NOI18N
91
break;
92             case REF_TYPE_FILE:
93                 bundleID = "LBL_BrokenLinksCustomizer_BrokenFileReference";
94                 break;
95             case REF_TYPE_PLATFORM:
96                 bundleID = "LBL_BrokenLinksCustomizer_BrokenPlatform";
97                 break;
98             default:
99                 assert false;
100                 return null;
101         }
102         return NbBundle.getMessage(BrokenReferencesCustomizer.class, bundleID, or.getDisplayID());
103     }
104
105     public String JavaDoc getDesciption(int index) {
106         OneReference or = getOneReference(index);
107         String JavaDoc bundleID;
108         switch (or.type) {
109             case REF_TYPE_LIBRARY:
110                 bundleID = "LBL_BrokenLinksCustomizer_BrokenLibraryDesc"; // NOI18N
111
break;
112             case REF_TYPE_LIBRARY_CONTENT:
113                 bundleID = "LBL_BrokenLinksCustomizer_BrokenLibraryContentDesc"; // NOI18N
114
break;
115             case REF_TYPE_PROJECT:
116                 bundleID = "LBL_BrokenLinksCustomizer_BrokenProjectReferenceDesc"; // NOI18N
117
break;
118             case REF_TYPE_FILE:
119                 bundleID = "LBL_BrokenLinksCustomizer_BrokenFileReferenceDesc";
120                 break;
121             case REF_TYPE_PLATFORM:
122                 bundleID = "LBL_BrokenLinksCustomizer_BrokenPlatformDesc";
123                 break;
124             default:
125                 assert false;
126                 return null;
127         }
128         return NbBundle.getMessage(BrokenReferencesCustomizer.class, bundleID, or.getDisplayID());
129     }
130
131     public OneReference getOneReference(int index) {
132         assert index>=0 && index<references.size();
133         return references.get(index);
134     }
135     
136     public boolean isBroken(int index) {
137         return references.get(index).broken;
138     }
139     
140     public int getSize() {
141         return references.size();
142     }
143
144     public static boolean isBroken(AntProjectHelper helper, PropertyEvaluator evaluator, String JavaDoc[] props, String JavaDoc[] platformsProps) {
145         Set JavaDoc<OneReference> s = getReferences(helper, evaluator, props, true);
146         if (s.size() > 0) {
147             return true;
148         }
149         s = getPlatforms(evaluator, platformsProps, true);
150         return s.size() > 0;
151     }
152
153     private static Set JavaDoc<OneReference> getReferences(AntProjectHelper helper, PropertyEvaluator evaluator, String JavaDoc[] ps, boolean abortAfterFirstProblem) {
154         Set JavaDoc<OneReference> set = new LinkedHashSet JavaDoc<OneReference>();
155         StringBuffer JavaDoc all = new StringBuffer JavaDoc();
156         for (String JavaDoc p : ps) {
157             // evaluate given property and tokenize it
158

159             String JavaDoc prop = evaluator.getProperty(p);
160             if (prop == null) {
161                 continue;
162             }
163             String JavaDoc[] vals = PropertyUtils.tokenizePath(prop);
164                         
165             // no check whether after evaluating there are still some
166
// references which could not be evaluated
167
for (String JavaDoc v : vals) {
168                 // we are checking only: project reference, file reference, library reference
169
if (!(v.startsWith("${file.reference.") || v.startsWith("${project.") || v.startsWith("${libs."))) {
170                     all.append(v);
171                     continue;
172                 }
173                 if (v.startsWith("${project.")) {
174                     // something in the form: "${project.<projID>}/dist/foo.jar"
175
String JavaDoc val = v.substring(2, v.indexOf('}'));
176                     set.add(new OneReference(REF_TYPE_PROJECT, val, true));
177                 } else {
178                     int type = REF_TYPE_LIBRARY;
179                     if (v.startsWith("${file.reference")) {
180                         type = REF_TYPE_FILE;
181                     }
182                     String JavaDoc val = v.substring(2, v.length() - 1);
183                     set.add(new OneReference(type, val, true));
184                 }
185                 if (abortAfterFirstProblem) {
186                     break;
187                 }
188             }
189             if (set.size() > 0 && abortAfterFirstProblem) {
190                 break;
191             }
192         }
193         
194         // Check also that all referenced project really exist and are reachable.
195
// If they are not report them as broken reference.
196
// XXX: there will be API in PropertyUtils for listing of Ant
197
// prop names in String. Consider using it here.
198
for (Map.Entry JavaDoc<String JavaDoc, String JavaDoc> entry : evaluator.getProperties().entrySet()) {
199             String JavaDoc key = entry.getKey();
200             String JavaDoc value = entry.getValue();
201             if (key.startsWith("project.")) { // NOI18N
202
File JavaDoc f = getFile(helper, evaluator, value);
203                 if (f.exists()) {
204                     continue;
205                 }
206                 // Check that the value is really used by some property.
207
// If it is not then ignore such a project.
208
if (all.indexOf(value) == -1) {
209                     continue;
210                 }
211                 set.add(new OneReference(REF_TYPE_PROJECT, key, true));
212             }
213             else if (key.startsWith("file.reference")) { //NOI18N
214
File JavaDoc f = getFile(helper, evaluator, value);
215                 if (f.exists() || all.indexOf(value) == -1) {
216                     continue;
217                 }
218                 set.add(new OneReference(REF_TYPE_FILE, key, true));
219             }
220         }
221         
222         //Check for libbraries with broken classpath content
223
Set JavaDoc<String JavaDoc> usedLibraries = new HashSet JavaDoc<String JavaDoc>();
224         Pattern JavaDoc libPattern = Pattern.compile("\\$\\{(lib.[-._a-zA-Z0-9]+.classpath)\\}"); //NOI18N
225
EditableProperties ep = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
226         for (String JavaDoc p : ps) {
227             String JavaDoc propertyValue = ep.getProperty(p);
228             if (propertyValue != null) {
229                 for (String JavaDoc v : PropertyUtils.tokenizePath(propertyValue)) {
230                     Matcher JavaDoc m = libPattern.matcher(v);
231                     if (m.matches()) {
232                         usedLibraries.add (m.group(1));
233                     }
234                 }
235             }
236         }
237         for (String JavaDoc libraryRef : usedLibraries) {
238             String JavaDoc libraryName = libraryRef.substring(5,libraryRef.length()-10);
239             Library lib = LibraryManager.getDefault().getLibrary (libraryName);
240             if (lib == null) {
241                 set.add(new OneReference(REF_TYPE_LIBRARY, libraryRef, true));
242             }
243             else {
244                 //XXX: Should check all the volumes (sources, javadoc, ...)?
245
for (URL JavaDoc url : lib.getContent("classpath")) { // NOI18N
246
if ("jar".equals(url.getProtocol())) { //NOI18N
247
url = FileUtil.getArchiveFile (url);
248                     }
249                     if (URLMapper.findFileObject (url) == null) {
250                         set.add(new OneReference(REF_TYPE_LIBRARY_CONTENT, libraryRef, true));
251                     }
252                 }
253             }
254         }
255         
256         return set;
257     }
258     
259     private static File JavaDoc getFile (AntProjectHelper helper, PropertyEvaluator evaluator, String JavaDoc name) {
260         if (helper != null) {
261             return new File JavaDoc(helper.resolvePath(name));
262         } else {
263             File JavaDoc f = new File JavaDoc(name);
264             if (!f.exists()) {
265                 // perhaps the file is relative?
266
String JavaDoc basedir = evaluator.getProperty("basedir");
267                 assert basedir != null;
268                 f = new File JavaDoc(new File JavaDoc(basedir), name);
269             }
270             return f;
271         }
272     }
273
274     private static Set JavaDoc<OneReference> getPlatforms(PropertyEvaluator evaluator, String JavaDoc[] platformsProps, boolean abortAfterFirstProblem) {
275         Set JavaDoc<OneReference> set = new LinkedHashSet JavaDoc<OneReference>();
276         for (String JavaDoc pprop : platformsProps) {
277             String JavaDoc prop = evaluator.getProperty(pprop);
278             if (prop == null) {
279                 continue;
280             }
281             if (!existPlatform(prop)) {
282                 
283                 // XXX: the J2ME stores in project.properties also platform
284
// display name and so show this display name instead of just
285
// prop ID if available.
286
if (evaluator.getProperty(pprop + ".description") != null) {
287                     prop = evaluator.getProperty(pprop + ".description");
288                 }
289                 
290                 set.add(new OneReference(REF_TYPE_PLATFORM, prop, true));
291             }
292             if (set.size() > 0 && abortAfterFirstProblem) {
293                 break;
294             }
295         }
296         return set;
297     }
298     
299     private static void updateReferencesList(List JavaDoc<OneReference> oldBroken, Set JavaDoc<OneReference> newBroken) {
300         for (OneReference or : oldBroken) {
301             if (newBroken.contains(or)) {
302                 or.broken = true;
303             } else {
304                 or.broken = false;
305             }
306         }
307         for (OneReference or : newBroken) {
308             if (!oldBroken.contains(or)) {
309                 oldBroken.add(or);
310             }
311         }
312     }
313     
314     private static boolean existPlatform(String JavaDoc platform) {
315         if (platform.equals("default_platform")) { // NOI18N
316
return true;
317         }
318         for (JavaPlatform plat : JavaPlatformManager.getDefault().getInstalledPlatforms()) {
319             // XXX: this should be defined as PROPERTY somewhere
320
if (platform.equals(plat.getProperties().get("platform.ant.name")) && // NOI18N
321
plat.getInstallFolders().size() > 0) {
322                 return true;
323             }
324         }
325         return false;
326     }
327
328     // XXX: perhaps could be moved to ReferenceResolver.
329
// But nobody should need it so it is here for now.
330
void updateReference(int index, File JavaDoc file) {
331         updateReference0(index, file);
332         // #48210 - check whether the folder does not contain other jars
333
// which could auto resolve some broken links:
334
OneReference or = getOneReference(index);
335         if (or.getType() != REF_TYPE_FILE) {
336             return;
337         }
338         for (int i=0; i<getSize(); i++) {
339             if (!isBroken(i) || i == index) {
340                 continue;
341             }
342             or = getOneReference(i);
343             if (or.getType() != REF_TYPE_FILE) {
344                 continue;
345             }
346             File JavaDoc f = new File JavaDoc(file.getParentFile(), or.getDisplayID());
347             if (f.exists()) {
348                 updateReference0(i, f);
349             }
350         }
351     }
352     
353     private void updateReference0(int index, File JavaDoc file) {
354         final String JavaDoc reference = getOneReference(index).ID;
355         FileObject myProjDirFO = helper.getProjectDirectory();
356         File JavaDoc myProjDir = FileUtil.toFile(myProjDirFO);
357         final String JavaDoc propertiesFile = AntProjectHelper.PRIVATE_PROPERTIES_PATH;
358         final String JavaDoc path = file.getAbsolutePath();
359         Project p;
360         try {
361             p = ProjectManager.getDefault().findProject(myProjDirFO);
362         } catch (IOException JavaDoc ex) {
363             ErrorManager.getDefault().notify(ErrorManager.ERROR, ex);
364             p = null;
365         }
366         final Project proj = p;
367         ProjectManager.mutex().postWriteRequest(new Runnable JavaDoc() {
368                 public void run() {
369                     EditableProperties props = helper.getProperties(propertiesFile);
370                     if (!path.equals(props.getProperty(reference))) {
371                         props.setProperty(reference, path);
372                         helper.putProperties(propertiesFile, props);
373                     }
374                     
375                     // #47541 - check that property is not defined in opposite
376
props = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
377                     if (props.containsKey(reference)) {
378                         props.remove(reference);
379                         helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, props);
380                     }
381                     
382                     if (proj != null) {
383                         try {
384                             ProjectManager.getDefault().saveProject(proj);
385                         } catch (IOException JavaDoc ex) {
386                             ErrorManager.getDefault().notify(ErrorManager.WARNING, ex);
387                         }
388                     }
389                 }
390             });
391     }
392
393     public static final int REF_TYPE_PROJECT = 1;
394     public static final int REF_TYPE_FILE = 2;
395     public static final int REF_TYPE_LIBRARY = 3;
396     public static final int REF_TYPE_PLATFORM = 4;
397     public static final int REF_TYPE_LIBRARY_CONTENT = 5;
398     
399     public static class OneReference {
400         
401         private int type;
402         private boolean broken;
403         private String JavaDoc ID;
404
405         public OneReference(int type, String JavaDoc ID, boolean broken) {
406             this.type = type;
407             this.ID = ID;
408             this.broken = broken;
409         }
410         
411         public int getType() {
412             return type;
413         }
414         
415         public String JavaDoc getDisplayID() {
416             switch (type) {
417                 
418                 case REF_TYPE_LIBRARY:
419                 case REF_TYPE_LIBRARY_CONTENT:
420                     // libs.<name>.classpath
421
return ID.substring(5, ID.length()-10);
422                     
423                 case REF_TYPE_PROJECT:
424                     // project.<name>
425
return ID.substring(8);
426                     
427                 case REF_TYPE_FILE:
428                     // file.reference.<name>
429
return ID.substring(15);
430                     
431                 case REF_TYPE_PLATFORM:
432                     return ID;
433                     
434                 default:
435                     assert false;
436                     return ID;
437             }
438         }
439
440         public boolean equals(Object JavaDoc o) {
441             if (o == this) {
442                 return true;
443             }
444             if (!(o instanceof OneReference)) {
445                 return false;
446             }
447             OneReference or = (OneReference)o;
448             return (this.type == or.type && this.ID.equals(or.ID));
449         }
450         
451         public int hashCode() {
452             int result = 7*type;
453             result = 31*result + ID.hashCode();
454             return result;
455         }
456         
457     }
458     
459 }
460
Popular Tags