2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6
* The contents of this file are subject to the terms of either the GNU
7
* General Public License Version 2 only ("GPL") or the Common
8
* Development and Distribution License("CDDL") (collectively, the
9
* "License"). You may not use this file except in compliance with the
10
* License. You can obtain a copy of the License at
11
* http://www.netbeans.org/cddl-gplv2.html
12
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
* specific language governing permissions and limitations under the
14
* License. When distributing the software, include this License Header
15
* Notice in each file and include the License file at
16
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17
* particular file as subject to the "Classpath" exception as provided
18
* by Sun in the GPL Version 2 section of the License file that
19
* accompanied this code. If applicable, add the following below the
20
* License Header, with the fields enclosed by brackets [] replaced by
21
* your own identifying information:
22
* "Portions Copyrighted [year] [name of copyright owner]"
26
* The Original Software is NetBeans. The Initial Developer of the Original
27
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
* Microsystems, Inc. All Rights Reserved.
30
* If you wish your version of this file to be governed by only the CDDL
31
* or only the GPL Version 2, indicate your decision by adding
32
* "[Contributor] elects to include this software in this distribution
33
* under the [CDDL or GPL Version 2] license." If you do not indicate a
34
* single choice of license, a recipient has the option to distribute
35
* your version of this file under either the CDDL, the GPL Version 2 or
36
* to extend the choice of license to its licensees as provided above.
37
* However, if you add GPL Version 2 code and therefore, elected the GPL
38
* Version 2 license, then the option applies only if the new code is
39
* made subject to such option by the copyright holder.
42
package org.netbeans.modules.projectimport.eclipse;
45
import java.util.ArrayList;
46
import java.util.Collection;
47
import java.util.Collections;
48
import java.util.HashMap;
49
import java.util.HashSet;
50
import java.util.Iterator;
53
import java.util.logging.Logger;
54
import org.netbeans.modules.projectimport.LoggerFactory;
55
import org.openide.filesystems.FileUtil;
58
* Represents Eclipse project structure.
62
public final class EclipseProject implements Comparable {
64
/** Logger for this class. */
65
private static final Logger logger =
66
LoggerFactory.getDefault().createLogger(EclipseProject.class);
68
static final String PROJECT_FILE = ".project"; // NOI18N
69
static final String CLASSPATH_FILE = ".classpath"; // NOI18N
71
private Workspace workspace;
74
private boolean internal = true;
75
private boolean javaNature;
78
private Set otherNatures;
80
private final File projectDir;
81
private final File cpFile;
82
private final File prjFile;
83
private String jdkDirectory;
86
* Returns <code>EclipseProject</code> instance representing Eclipse project
87
* found in the given <code>projectDir</code>. If a project is not found in
88
* the specified directory, <code>null</code> is returned.
90
* @return either a <code>EclipseProject</code> instance or null if a given
91
* <code>projectDir</code> doesn't contain valid Eclipse project.
93
static EclipseProject createProject(File projectDir) {
94
if (!EclipseUtils.isRegularProject(projectDir)) {
95
logger.fine(projectDir + " doesn't contain regular Eclipse project."); // NOI18N
98
return new EclipseProject(projectDir);
101
/** Sets up a project directory. */
102
private EclipseProject(File projectDir) {
103
this.projectDir = projectDir;
104
this.cpFile = new File(projectDir, CLASSPATH_FILE);
105
this.prjFile = new File(projectDir, PROJECT_FILE);
108
void setWorkspace(Workspace workspace) {
109
this.workspace = workspace;
112
public Workspace getWorkspace() {
116
void setClassPath(ClassPath cp) {
120
ClassPath getClassPath() {
125
* Returns project's name.
127
public String getName() {
131
void setName(String name) {
135
void setInternal(boolean internal) {
136
this.internal = internal;
139
public boolean isInternal() {
143
public File getDirectory() {
148
* Returns metadata file containing information about this projects. I.e.
149
* normally <em>.project</em> file withing the project's directory. See
150
* {@link #PROJECT_FILE}.
152
File getProjectFile() {
157
* Returns metadata file containing information about this projects. I.e.
158
* normally <em>.classpath</em> file withing the project's directory. See
159
* {@link #CLASSPATH_FILE}.
161
File getClassPathFile() {
165
public boolean hasJavaNature() {
169
void setJavaNature(boolean javaNature) {
170
this.javaNature = javaNature;
173
public Set getOtherNatures() {
177
void addOtherNature(String nature) {
178
if (otherNatures == null) {
179
otherNatures = new HashSet();
181
logger.fine("Project " + getName() + " has another nature: " + // NOI18N
183
otherNatures.add(nature);
187
* Returns JDK directory for platform this project uses. Can be null in a
188
* case when a JDK was set for an eclipse project in Eclipse then the
189
* directory with JDK was deleted from filesystem and then a project is
190
* imported to NetBeans.
192
* @return JDK directory for the project
194
public String getJDKDirectory() {
195
if (jdkDirectory == null && workspace != null) {
196
logger.finest("Getting JDK directory for project " + this.getName()); // NOI18N
197
jdkDirectory = workspace.getJDKDirectory(cp.getJREContainer());
198
logger.finest("Resolved JDK directory: " + jdkDirectory); // NOI18N
199
// jdkDirectory = workspace.getJDKDirectory(projectDir.getName());
204
/** Convenient delegate to <code>ClassPath</code> */
205
public Collection getSourceRoots() {
206
return cp.getSourceRoots();
210
* Returns map of file-label entries representing Eclipse project's source
213
public Map/*<File, String>*/ getAllSourceRoots() {
214
Map rootsLabels = new HashMap();
217
Collection srcRoots = cp.getSourceRoots();
218
for (Iterator it = srcRoots.iterator(); it.hasNext(); ) {
219
ClassPathEntry cpe = (ClassPathEntry) it.next();
220
File file = FileUtil.normalizeFile(new File(cpe.getAbsolutePath()));
221
rootsLabels.put(file, cpe.getRawPath());
224
Collection extSrcRoots = cp.getExternalSourceRoots();
225
for (Iterator it = extSrcRoots.iterator(); it.hasNext(); ) {
226
ClassPathEntry cpe = (ClassPathEntry) it.next();
228
FileUtil.normalizeFile(new File(cpe.getAbsolutePath())),
236
* Returns all libraries on the project classpath.
238
public Collection/*<File>*/ getAllLibrariesFiles() {
239
Collection files = new ArrayList();
240
// internal libraries
241
for (Iterator it = cp.getLibraries().iterator(); it.hasNext(); ) {
242
files.add(FileUtil.normalizeFile(new File(((ClassPathEntry)it.next()).getAbsolutePath())));
245
// external libraries
246
for (Iterator it = cp.getExternalLibraries().iterator(); it.hasNext(); ) {
247
files.add(FileUtil.normalizeFile(new File(((ClassPathEntry)it.next()).getAbsolutePath())));
249
// jars in user libraries
250
for (Iterator it = getUserLibrariesJars().iterator(); it.hasNext(); ) {
251
files.add(FileUtil.normalizeFile(new File((String) it.next())));
254
for (Iterator it = cp.getVariables().iterator(); it.hasNext(); ) {
255
ClassPathEntry entry = (ClassPathEntry)it.next();
256
// in case a variable wasn't resolved
257
if (entry.getAbsolutePath() != null) {
258
files.add(FileUtil.normalizeFile(new File(entry.getAbsolutePath())));
264
/** Convenient delegate to <code>ClassPath</code> */
265
public Collection getExternalSourceRoots() {
266
return cp.getExternalSourceRoots();
269
/** Convenient delegate to <code>ClassPath</code> */
270
public Collection getLibraries() {
271
return cp.getLibraries();
274
/** Convenient delegate to <code>ClassPath</code> */
275
public Collection getExternalLibraries() {
276
return cp.getExternalLibraries();
279
public Collection getUserLibrariesJars() {
280
Collection userLibrariesJars = new HashSet();
281
if (workspace != null) {
282
for (Iterator it = cp.getUserLibraries().iterator(); it.hasNext(); ) {
283
userLibrariesJars.addAll(
284
workspace.getJarsForUserLibrary((String) it.next()));
287
return userLibrariesJars;
290
/** Convenient delegate to <code>ClassPath</code> */
291
public Collection getProjectsEntries() {
292
return cp.getProjects();
295
private Set projectsWeDependOn;
298
* Returns collection of <code>EclipseProject</code> this project requires.
300
public Set getProjects() {
301
if (workspace != null && projectsWeDependOn == null) {
302
projectsWeDependOn = new HashSet();
303
for (Iterator it = cp.getProjects().iterator(); it.hasNext(); ) {
304
ClassPathEntry cp = (ClassPathEntry) it.next();
305
EclipseProject prj = workspace.getProjectByRawPath(cp.getRawPath());
307
projectsWeDependOn.add(prj);
311
return projectsWeDependOn == null ?
312
Collections.EMPTY_SET : projectsWeDependOn;
315
/** Convenient delegate to <code>ClassPath</code> */
316
public Collection getVariables() {
317
return cp.getVariables();
320
void addLink(ClassPath.Link link) {
322
links = new HashSet();
328
* Inteligently sets absolute path for a given entry with recongnizing of
329
* links, projects, variables, relative and absolute entries.
330
* If it is not possible (e.g. workspace Varible is not found) sets abs.
333
void setAbsolutePathForEntry(ClassPathEntry entry) {
334
// set abs. path default (null)
335
entry.setAbsolutePath(null);
337
// try to resolve entry as a CONTAINER
338
if (entry.getType() == ClassPathEntry.TYPE_CONTAINER) {
339
// we don't support CONTAINERs so we don't care about them here
340
// (we support JRE/JDK containers but those are solved elsewhere)
344
// try to resolve entry as a VARIABLE
345
if (entry.getType() == ClassPathEntry.TYPE_VARIABLE) {
346
String rawPath = entry.getRawPath();
347
int slashIndex = rawPath.indexOf('/');
348
if (slashIndex != -1) {
349
Workspace.Variable parent = getVariable(
350
rawPath.substring(0, slashIndex));
351
if (parent != null) {
352
entry.setAbsolutePath(parent.getLocation() +
353
rawPath.substring(slashIndex));
356
Workspace.Variable var = getVariable(entry);
358
entry.setAbsolutePath(var.getLocation());
364
// try to resolve entry as a PROJECT
365
if (entry.getType() == ClassPathEntry.TYPE_PROJECT) {
366
if (workspace != null) {
367
entry.setAbsolutePath(workspace.getProjectAbsolutePath(
368
entry.getRawPath().substring(1)));
371
// ErrorManager.getDefault().log(ErrorManager.WARNING, "workspace == null");
376
// try to resolve entry as a LINK
377
ClassPath.Link link = getLink(entry.getRawPath());
379
logger.finest("Found link for entry \"" + entry + "\": " + link); // NOI18N
380
if (FileUtil.normalizeFile(new File(link.getLocation())).exists()) {
381
// change type from source to source link
382
entry.setType(ClassPathEntry.TYPE_LINK);
383
entry.setAbsolutePath(link.getLocation());
385
logger.info("Not able to resolve absolute path for classpath" + // NOI18N
386
" entry \"" + entry.getRawPath() + "\". This classpath" + // NOI18N
387
" entry is external source which points to PATH VARIABLE" + // NOI18N
388
" which points to final destination. This feature will be" + // NOI18N
389
" supported in future version of Importer."); // NOI18N
390
entry.setType(ClassPathEntry.TYPE_UNKNOWN);
395
// not VARIABLE, not PROJECT, not LINK -> either source root or library
396
if (entry.isRawPathRelative()) {
397
// internal src or lib
398
entry.setAbsolutePath(projectDir.getAbsolutePath() + File.separator
399
+ entry.getRawPath());
401
// external src or lib
402
entry.setAbsolutePath(entry.getRawPath());
407
* Find variable for the given variable rawPath. Note that this method
408
* returns <code>null</code> if workspace wasn't set for the project.
410
private Workspace.Variable getVariable(String rawPath) {
411
if (workspace == null) {
412
// workspace wasn't set for this project
413
logger.fine("Workspace wasn't set for the project \"" + getName() + "\""); // NOI18N
416
Set variables = workspace.getVariables();
417
if (variables != null) {
418
for (Iterator it = workspace.getVariables().iterator(); it.hasNext(); ) {
419
Workspace.Variable variable = (Workspace.Variable) it.next();
420
if (variable.getName().equals(rawPath)) {
425
logger.info("Cannot resolve variable for raw path: " + rawPath); // NOI18N
430
* Recongises if a given entry represents variable. If yes returns variable
431
* it represents otherwise null. Note that this method returns null if
432
* workspace wasn't set for this project.
434
private Workspace.Variable getVariable(ClassPathEntry entry) {
435
return getVariable(entry.getRawPath());
439
* Recongises if a given entry represents link. If yes returns link it
440
* represents otherwise null.
442
private ClassPath.Link getLink(String linkName) {
444
for (Iterator it = links.iterator(); it.hasNext(); ) {
445
ClassPath.Link link = (ClassPath.Link) it.next();
446
if (link.getName().equals(linkName)) {
454
public String toString() {
455
return "EclipseProject[" + getName() + ", " + getDirectory() + "]"; // NOI18N
458
/* name is enough for now */
459
public boolean equals(Object obj) {
460
if (this == obj) return true;
461
if (!(obj instanceof EclipseProject)) return false;
462
final EclipseProject ePrj = (EclipseProject) obj;
463
if (!name.equals(ePrj.name)) return false;
467
/* name is enough for now */
468
public int hashCode() {
470
result = 37 * result + System.identityHashCode(name);
475
* Compares projects based on theirs <code>name</code>s. Projects which has
476
* null-name will be last.
478
public int compareTo(Object o) {
479
String name1 = getName();
481
if (o instanceof EclipseProject) {
482
name2 = ((EclipseProject) o).getName();
485
return (name1 == null ? 0 : -1);
487
return (name1 == null ? 1 : name1.compareToIgnoreCase(name2));