KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > projectimport > eclipse > Importer


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.projectimport.eclipse;
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.Collection JavaDoc;
27 import java.util.HashMap JavaDoc;
28 import java.util.HashSet JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.Map JavaDoc;
31 import java.util.Set JavaDoc;
32 import java.util.logging.Logger JavaDoc;
33 import org.netbeans.api.java.platform.JavaPlatform;
34 import org.netbeans.api.java.platform.JavaPlatformManager;
35 import org.netbeans.api.java.project.JavaProjectConstants;
36 import org.netbeans.api.project.ProjectManager;
37 import org.netbeans.api.project.ant.AntArtifact;
38 import org.netbeans.api.project.ant.AntArtifactQuery;
39 import org.netbeans.modules.java.j2seplatform.platformdefinition.PlatformConvertor;
40 import org.netbeans.modules.java.j2seplatform.wizard.NewJ2SEPlatform;
41 import org.netbeans.modules.java.j2seproject.J2SEProject;
42 import org.netbeans.modules.java.j2seproject.J2SEProjectGenerator;
43 import org.netbeans.modules.java.j2seproject.J2SEProjectType;
44 import org.netbeans.modules.java.j2seproject.SourceRoots;
45 import org.netbeans.modules.java.j2seproject.ui.customizer.J2SEProjectProperties;
46 import org.netbeans.modules.projectimport.LoggerFactory;
47 import org.netbeans.spi.java.project.classpath.ProjectClassPathExtender;
48 import org.netbeans.spi.project.support.ant.AntProjectHelper;
49 import org.netbeans.spi.project.support.ant.EditableProperties;
50 import org.netbeans.spi.project.support.ant.PropertyUtils;
51 import org.openide.ErrorManager;
52 import org.openide.filesystems.FileObject;
53 import org.openide.filesystems.FileUtil;
54 import org.openide.filesystems.Repository;
55 import org.openide.loaders.DataFolder;
56 import org.openide.loaders.DataObject;
57 import org.openide.util.NbBundle;
58 import org.openide.util.RequestProcessor;
59 import org.w3c.dom.Element JavaDoc;
60
61 /**
62  * Able to import given Eclipse projects in separate thread with providing
63  * information about current state(progress). Converts eclipse projects and
64  * their required projects into NetBeans ones and stores them into the given
65  * destination.
66  *
67  * @author mkrauskopf
68  */

69 final class Importer {
70     
71     /** Logger for this class. */
72     private static final Logger JavaDoc logger =
73             LoggerFactory.getDefault().createLogger(Importer.class);
74     
75     private final Set JavaDoc/*<EclipseProject>*/ eclProjects;
76     private final String JavaDoc destination;
77     private final boolean recursively;
78     private J2SEProject[] nbProjects;
79     private final Set JavaDoc/*<String>*/ recursionCheck;
80     private final Map JavaDoc/*<String, J2SEProject>*/ loadedProject;
81     
82     private int nOfProcessed;
83     private String JavaDoc progressInfo;
84     private boolean done;
85     private Collection JavaDoc warnings;
86     
87     private JavaPlatform[] nbPlfs; // All netbeans platforms
88
private File JavaDoc nbDefPlfFile; // NetBeans default platform directory
89

90     Importer(final Set JavaDoc/*<EclipseProject>*/ eclProjects, String JavaDoc destination, boolean recursively) {
91         this.eclProjects = eclProjects;
92         this.destination = destination;
93         this.recursively = recursively;
94         this.nbProjects = new J2SEProject[eclProjects.size()];
95         recursionCheck = new HashSet JavaDoc();
96         loadedProject = new HashMap JavaDoc();
97     }
98     
99     /**
100      * Starts importing process in separated thread. Use getters to obtain
101      * information about current progress.
102      */

103     void startImporting() {
104         nbPlfs = JavaPlatformManager.getDefault().getInstalledPlatforms();
105         JavaPlatform defPlf = JavaPlatformManager.getDefault().getDefaultPlatform();
106         Collection JavaDoc installFolder = defPlf.getInstallFolders();
107         if (installFolder.isEmpty()) {
108             logWarning(NbBundle.getMessage(Importer.class, "MSG_NotValidPlatformsInNB")); // NOI18N
109
return;
110         } else {
111             nbDefPlfFile = FileUtil.toFile((FileObject) installFolder.toArray()[0]);
112         }
113         RequestProcessor.getDefault().post(new Runnable JavaDoc() {
114             public void run() {
115                 ProjectManager.mutex().writeAccess(new Runnable JavaDoc() {
116                     public void run() {
117                         try {
118                             int pos = 0;
119                             for (Iterator JavaDoc it = eclProjects.iterator(); it.hasNext(); ) {
120                                 EclipseProject eclPrj = (EclipseProject) it.next();
121                                 nbProjects[pos++] = importProject(eclPrj);
122                             }
123                         } catch (IOException JavaDoc ioe) {
124                             Throwable JavaDoc t = ErrorManager.getDefault().annotate(ioe,
125                                     "Error occured during project importing"); // NOI18N
126
ErrorManager.getDefault().notify(ErrorManager.USER, t);
127                         } finally {
128                             done = true;
129                         }
130                     }
131                 });
132             }
133         });
134     }
135     
136     /**
137      * Returns number of already processed projects.
138      */

139     int getNOfProcessed() {
140         return nOfProcessed;
141     }
142     
143     /**
144      * Returns localized message describing current importer activity.
145      */

146     String JavaDoc getProgressInfo() {
147         return progressInfo;
148     }
149     
150     /**
151      * Returns whether importer has finished.
152      */

153     boolean isDone() {
154         return done;
155     }
156     
157     Collection JavaDoc getWarnings() {
158         return warnings;
159     }
160     
161     /**
162      * Gets imported projects. Call after the importing <code>isDone()</code>.
163      */

164     J2SEProject[] getProjects() {
165         return nbProjects;
166     }
167     
168     private J2SEProject importProject(EclipseProject eclProject) throws IOException JavaDoc {
169         assert eclProject != null : "Eclipse project cannot be null"; // NOI18N
170

171         // recursivity check
172
if (!recursionCheck.add(eclProject.getDirectory().toString())) {
173             J2SEProject project = (J2SEProject) loadedProject.get(
174                     eclProject.getDirectory().getAbsolutePath());
175             return project;
176         }
177         logger.finer("Importing of project: \"" + // NOI18N
178
eclProject.getDirectory().getAbsolutePath() + "\" started"); // NOI18N
179
nOfProcessed++;
180         progressInfo = NbBundle.getMessage(Importer.class,
181                 "MSG_Progress_ProcessingProject", eclProject.getName()); // NOI18N
182
File JavaDoc nbProjectDir = FileUtil.normalizeFile(new File JavaDoc(destination + "/" + eclProject.getName())); // NOI18N
183
Map JavaDoc eclRoots = eclProject.getAllSourceRoots();
184         File JavaDoc[] testDirs = new File JavaDoc[0];
185         File JavaDoc[] srcFiles = new File JavaDoc[eclRoots.size()];
186         int j = 0;
187         for (Iterator JavaDoc it = eclRoots.keySet().iterator(); it.hasNext(); ) {
188             srcFiles[j++] = (File JavaDoc) it.next();
189         }
190         // create basic NB project
191
final AntProjectHelper helper = J2SEProjectGenerator.createProject(
192                 nbProjectDir, eclProject.getName(), srcFiles, testDirs, null);
193         // get NB project
194
J2SEProject nbProject = (J2SEProject) ProjectManager.getDefault().
195                 findProject(FileUtil.toFileObject(
196                 FileUtil.normalizeFile(nbProjectDir)));
197         ProjectClassPathExtender nbProjectClassPath =
198                 (ProjectClassPathExtender) nbProject.getLookup().lookup(ProjectClassPathExtender.class);
199         assert nbProjectClassPath != null : "Cannot lookup ProjectClassPathExtender"; // NOI18N
200

201         // set labels for source roots
202
SourceRoots roots = nbProject.getSourceRoots();
203         URL JavaDoc[] rootURLs = roots.getRootURLs();
204         String JavaDoc[] labels = new String JavaDoc[rootURLs.length];
205         for (int i = 0; i < rootURLs.length; i++) {
206             labels[i] = (String JavaDoc) eclRoots.get(new File JavaDoc(rootURLs[i].getFile()));
207         }
208         roots.putRoots(rootURLs, labels);
209         
210         // add libraries to classpath
211
for (Iterator JavaDoc it = eclProject.getAllLibrariesFiles().iterator(); it.hasNext(); ) {
212             File JavaDoc eclLib = (File JavaDoc) it.next();
213             if (eclLib.exists()) {
214                 nbProjectClassPath.addArchiveFile(FileUtil.toFileObject(
215                         FileUtil.normalizeFile(eclLib)));
216             } else {
217                 logWarning(NbBundle.getMessage(Importer.class, "MSG_LibraryDoesnExist", // NOI18N
218
eclProject.getName(), eclLib.getAbsolutePath()), true);
219             }
220         }
221         
222         // create projects the main project depends on
223
if (recursively) {
224             Collection JavaDoc projects = eclProject.getProjects();
225             for (Iterator JavaDoc it = projects.iterator(); it.hasNext(); ) {
226                 EclipseProject eclSubProject = (EclipseProject) it.next();
227                 J2SEProject nbSubProject = importProject(eclSubProject);
228                 // The project can be null when a cycle dependency is encountered.
229
// Just skip the dependency and try the best we can.
230
if (nbSubProject != null) {
231                     AntArtifact[] artifact =
232                             AntArtifactQuery.findArtifactsByType(nbSubProject,
233                             JavaProjectConstants.ARTIFACT_TYPE_JAR);
234                     nbProjectClassPath.addAntArtifact(
235                             artifact[0], artifact[0].getArtifactLocations()[0]);
236                 } else {
237                     logger.warning("Project in directory \"" + // NOI18N
238
eclProject.getDirectory().getAbsolutePath() +
239                             "\" is already being processed. Recursive " + // NOI18N
240
"dependencies reached. "); // NOI18N
241
}
242             }
243         }
244         
245         // set platform used by an Eclipse project
246
setJavaPlatform(eclProject, helper);
247         
248         ProjectManager.getDefault().saveProject(nbProject);
249         logger.finer("Project loaded: " + // NOI18N
250
eclProject.getDirectory().getAbsolutePath());
251         loadedProject.put(eclProject.getDirectory().getAbsolutePath(), nbProject);
252         return nbProject;
253     }
254     
255     /** Sets <code>JavaPlatform</code> for the given project */
256     private void setJavaPlatform(EclipseProject eclProject,
257             final AntProjectHelper helper) throws IOException JavaDoc {
258         // progressInfo = "Setting JDK for \"" + eclProject.getName() + "\"";
259
String JavaDoc eclPlfDir = eclProject.getJDKDirectory();
260         // eclPlfDir can be null in a case when a JDK was set for an eclipse
261
// project in Eclipse then the directory with JDK was deleted from
262
// filesystem and then a project is imported into NetBeans
263
if (eclPlfDir == null) {
264             return;
265         }
266         File JavaDoc eclPlfFile = FileUtil.normalizeFile(new File JavaDoc(eclPlfDir));
267         if (eclPlfFile.equals(nbDefPlfFile)) { // use default platform
268
return;
269         }
270         JavaPlatform nbPlf = null;
271         for (int i = 0; i < nbPlfs.length; i++) {
272             JavaPlatform current = nbPlfs[i];
273             Collection JavaDoc instFolders = current.getInstallFolders();
274             if (instFolders.isEmpty()) {
275                 logger.fine("Java platform \"" + current.getDisplayName() + // NOI18N
276
"\" is not valid. Skipping..."); // NOI18N
277
continue;
278             }
279             File JavaDoc nbPlfDir = FileUtil.toFile((FileObject) instFolders.toArray()[0]);
280             if (nbPlfDir.equals(eclPlfFile)) {
281                 nbPlf = nbPlfs[i];
282                 // found
283
break;
284             }
285         }
286         // If we are not able to find any platform let's use the "broken
287
// platform" which can be easily added by user with "Resolve Reference
288
// Problems" feature. Such behaviour is much better then using a default
289
// platform when user imports more projects.
290
if (nbPlf == null) {
291             logger.fine("Creating new platform: " + eclPlfFile.getAbsolutePath()); // NOI18N
292
FileObject fo = FileUtil.toFileObject(eclPlfFile);
293             if (fo != null) {
294                 NewJ2SEPlatform plat = NewJ2SEPlatform.create(fo);
295                 plat.run();
296                 if (plat.isValid()) {
297                     if (plat.findTool("javac")!= null) { //NOI18N
298
String JavaDoc displayName = createPlatformDisplayName(plat);
299                         String JavaDoc antName = createPlatformAntName(displayName);
300                         plat.setDisplayName(displayName);
301                         plat.setAntName(antName);
302                         FileObject platformsFolder = Repository.getDefault().
303                                 getDefaultFileSystem().findResource(
304                                 "Services/Platforms/org-netbeans-api-java-Platform"); //NOI18N
305
assert platformsFolder != null;
306                         DataObject dobj = PlatformConvertor.create(plat,
307                                 DataFolder.findFolder(platformsFolder), antName);
308                         nbPlf = (JavaPlatform) dobj.getNodeDelegate().getLookup().
309                                 lookup(JavaPlatform.class);
310                         // update installed platform
311
nbPlfs = JavaPlatformManager.getDefault().getInstalledPlatforms();
312                     } else {
313                         logWarning(NbBundle.getMessage(Importer.class, "MSG_JRECannotBeUsed", // NOI18N
314
eclProject.getName()), true);
315                     }
316                 } else {
317                     // tzezula: TODO: User should be notified in the UI and
318
// probably default platform is used (not sure if it is
319
// according to UI spec)
320
logWarning( "Cannot create new J2SE platform, the " + // NOI18N
321
"default platform will be used."); // NOI18N
322
}
323             } else {
324                 logWarning(NbBundle.getMessage(Importer.class, "MSG_JDKDoesnExistUseDefault", // NOI18N
325
eclProject.getName(), eclPlfFile.getAbsolutePath()), true);
326             }
327         }
328         // tzezula: The platform is changed to explicit one only in case when
329
// the platform already existed or it was successfully created
330
if (nbPlf != null) {
331             Element JavaDoc pcd = helper.getPrimaryConfigurationData(true);
332             Element JavaDoc el = pcd.getOwnerDocument().createElementNS(
333                     J2SEProjectType.PROJECT_CONFIGURATION_NAMESPACE,
334                     "explicit-platform"); // NOI18N
335
pcd.appendChild(el);
336             helper.putPrimaryConfigurationData(pcd, true);
337             EditableProperties prop =
338                     helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
339             String JavaDoc ver = nbPlf.getSpecification().getVersion().toString();
340             String JavaDoc normalizedName = (String JavaDoc)nbPlf.getProperties().get(
341                     "platform.ant.name"); // NOI18N
342
prop.setProperty(J2SEProjectProperties.JAVAC_SOURCE, ver);
343             prop.setProperty(J2SEProjectProperties.JAVAC_TARGET, ver);
344             prop.setProperty(J2SEProjectProperties.JAVA_PLATFORM, normalizedName);
345             helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, prop);
346         } else {
347             logWarning("Setting of platform for project \"" // NOI18N
348
+ eclProject.getName() + "\" failed."); // NOI18N
349
}
350     }
351     
352     private void logWarning(String JavaDoc message) {
353         logWarning(message, false);
354     }
355     
356     /**
357      * Delegates to ErrorManager. When the <code>isGUIWarning</code> is true,
358      * the warning will be also shown to the user after importing is done.
359      */

360     private void logWarning(String JavaDoc message, boolean isGUIWarning) {
361         if (isGUIWarning) {
362             if (warnings == null) {
363                 warnings = new ArrayList JavaDoc();
364             }
365             warnings.add(message);
366         }
367         logger.warning(message);
368     }
369     
370     
371     private static String JavaDoc createPlatformDisplayName(JavaPlatform plat) {
372         Map JavaDoc m = plat.getSystemProperties();
373         String JavaDoc vmName = (String JavaDoc)m.get("java.vm.name"); //NOI18N
374
String JavaDoc vmVersion = (String JavaDoc)m.get("java.vm.version"); //NOI18N
375
StringBuffer JavaDoc displayName = new StringBuffer JavaDoc();
376         if (vmName != null) {
377             displayName.append(vmName);
378         }
379         if (vmVersion != null) {
380             if (displayName.length() > 0) {
381                 displayName.append(' ');
382             }
383             displayName.append(vmVersion);
384         }
385         return displayName.toString();
386     }
387     
388     private String JavaDoc createPlatformAntName(String JavaDoc displayName) {
389         assert displayName != null && displayName.length() > 0;
390         String JavaDoc antName = PropertyUtils.getUsablePropertyName(displayName);
391         if (platformExists(antName)) {
392             String JavaDoc baseName = antName;
393             int index = 1;
394             antName = baseName + Integer.toString(index);
395             while (platformExists(antName)) {
396                 index ++;
397                 antName = baseName + Integer.toString(index);
398             }
399         }
400         return antName;
401     }
402     
403     /**
404      * Checks if the platform of given antName is already installed
405      */

406     private boolean platformExists(String JavaDoc antName) {
407         assert antName != null && antName.length() > 0;
408         for (int i=0; i< nbPlfs.length; i++) {
409             String JavaDoc otherName = (String JavaDoc) nbPlfs[i].getProperties().get("platform.ant.name"); //NOI18N
410
if (antName.equals(otherName)) {
411                 return true;
412             }
413         }
414         return false;
415     }
416
417 }
418
Popular Tags