This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 153923
Collapse All | Expand All

(-)a/apisupport.project/nbproject/project.xml (-1 / +1 lines)
Lines 196-202 Link Here
196
                    <compile-dependency/>
196
                    <compile-dependency/>
197
                    <run-dependency>
197
                    <run-dependency>
198
                        <release-version>1</release-version>
198
                        <release-version>1</release-version>
199
                        <specification-version>1.21</specification-version>
199
                        <specification-version>1.28</specification-version>
200
                    </run-dependency>
200
                    </run-dependency>
201
                </dependency>
201
                </dependency>
202
                <dependency>
202
                <dependency>
(-)a/apisupport.project/src/org/netbeans/modules/apisupport/project/NbModuleProjectType.java (-2 / +8 lines)
Lines 42-57 Link Here
42
package org.netbeans.modules.apisupport.project;
42
package org.netbeans.modules.apisupport.project;
43
43
44
import java.io.IOException;
44
import java.io.IOException;
45
import javax.swing.Icon;
45
import org.netbeans.api.project.Project;
46
import org.netbeans.api.project.Project;
46
import org.netbeans.spi.project.support.ant.AntBasedProjectType;
47
import org.netbeans.spi.project.support.ant.AntBasedProjectType2;
47
import org.netbeans.spi.project.support.ant.AntProjectHelper;
48
import org.netbeans.spi.project.support.ant.AntProjectHelper;
49
import org.openide.util.ImageUtilities;
48
50
49
/**
51
/**
50
 * Factory for NetBeans module projects.
52
 * Factory for NetBeans module projects.
51
 * @author Jesse Glick
53
 * @author Jesse Glick
52
 */
54
 */
53
@org.openide.util.lookup.ServiceProvider(service=org.netbeans.spi.project.support.ant.AntBasedProjectType.class)
55
@org.openide.util.lookup.ServiceProvider(service=org.netbeans.spi.project.support.ant.AntBasedProjectType.class)
54
public final class NbModuleProjectType implements AntBasedProjectType {
56
public final class NbModuleProjectType implements AntBasedProjectType2 {
55
57
56
    static final String TYPE = "org.netbeans.modules.apisupport.project"; // NOI18N
58
    static final String TYPE = "org.netbeans.modules.apisupport.project"; // NOI18N
57
    static final String NAME_SHARED = "data"; // NOI18N
59
    static final String NAME_SHARED = "data"; // NOI18N
Lines 78-82 Link Here
78
    public String getPrimaryConfigurationDataElementNamespace(boolean shared) {
80
    public String getPrimaryConfigurationDataElementNamespace(boolean shared) {
79
        return shared ? NAMESPACE_SHARED : NAMESPACE_PRIVATE;
81
        return shared ? NAMESPACE_SHARED : NAMESPACE_PRIVATE;
80
    }
82
    }
83
84
    public Icon getIcon() {
85
        return ImageUtilities.image2Icon(ImageUtilities.loadImage("org/netbeans/modules/apisupport/project/resources/module.png", true));
86
    }
81
    
87
    
82
}
88
}
(-)a/apisupport.project/src/org/netbeans/modules/apisupport/project/suite/SuiteProjectType.java (-2 / +8 lines)
Lines 42-57 Link Here
42
package org.netbeans.modules.apisupport.project.suite;
42
package org.netbeans.modules.apisupport.project.suite;
43
43
44
import java.io.IOException;
44
import java.io.IOException;
45
import javax.swing.Icon;
45
import org.netbeans.api.project.Project;
46
import org.netbeans.api.project.Project;
46
import org.netbeans.spi.project.support.ant.AntBasedProjectType;
47
import org.netbeans.spi.project.support.ant.AntBasedProjectType2;
47
import org.netbeans.spi.project.support.ant.AntProjectHelper;
48
import org.netbeans.spi.project.support.ant.AntProjectHelper;
49
import org.openide.util.ImageUtilities;
48
50
49
/**
51
/**
50
 * Factory for NetBeans module suite projects.
52
 * Factory for NetBeans module suite projects.
51
 * @author Jesse Glick
53
 * @author Jesse Glick
52
 */
54
 */
53
@org.openide.util.lookup.ServiceProvider(service=org.netbeans.spi.project.support.ant.AntBasedProjectType.class)
55
@org.openide.util.lookup.ServiceProvider(service=org.netbeans.spi.project.support.ant.AntBasedProjectType.class)
54
public final class SuiteProjectType implements AntBasedProjectType {
56
public final class SuiteProjectType implements AntBasedProjectType2 {
55
57
56
    public static final String TYPE = "org.netbeans.modules.apisupport.project.suite"; // NOI18N
58
    public static final String TYPE = "org.netbeans.modules.apisupport.project.suite"; // NOI18N
57
    static final String NAME_SHARED = "data"; // NOI18N
59
    static final String NAME_SHARED = "data"; // NOI18N
Lines 77-81 Link Here
77
    public String getPrimaryConfigurationDataElementNamespace(boolean shared) {
79
    public String getPrimaryConfigurationDataElementNamespace(boolean shared) {
78
        return shared ? NAMESPACE_SHARED : NAMESPACE_PRIVATE;
80
        return shared ? NAMESPACE_SHARED : NAMESPACE_PRIVATE;
79
    }
81
    }
82
83
    public Icon getIcon() {
84
        return ImageUtilities.image2Icon(ImageUtilities.loadImage("org/netbeans/modules/apisupport/project/suite/resources/suite.png", true));
85
    }
80
    
86
    
81
}
87
}
(-)a/java.j2seproject/nbproject/project.xml (-1 / +1 lines)
Lines 180-186 Link Here
180
                    <compile-dependency/>
180
                    <compile-dependency/>
181
                    <run-dependency>
181
                    <run-dependency>
182
                        <release-version>1</release-version>
182
                        <release-version>1</release-version>
183
                        <specification-version>1.26</specification-version>
183
                        <specification-version>1.28</specification-version>
184
                    </run-dependency>
184
                    </run-dependency>
185
                </dependency>
185
                </dependency>
186
                <dependency>
186
                <dependency>
(-)a/java.j2seproject/src/org/netbeans/modules/java/j2seproject/J2SEProjectType.java (-2 / +8 lines)
Lines 42-57 Link Here
42
package org.netbeans.modules.java.j2seproject;
42
package org.netbeans.modules.java.j2seproject;
43
43
44
import java.io.IOException;
44
import java.io.IOException;
45
import javax.swing.Icon;
45
import org.netbeans.api.project.Project;
46
import org.netbeans.api.project.Project;
46
import org.netbeans.spi.project.support.ant.AntBasedProjectType;
47
import org.netbeans.spi.project.support.ant.AntBasedProjectType2;
47
import org.netbeans.spi.project.support.ant.AntProjectHelper;
48
import org.netbeans.spi.project.support.ant.AntProjectHelper;
49
import org.openide.util.ImageUtilities;
48
50
49
/**
51
/**
50
 * Factory for simple J2SE projects.
52
 * Factory for simple J2SE projects.
51
 * @author Jesse Glick
53
 * @author Jesse Glick
52
 */
54
 */
53
@org.openide.util.lookup.ServiceProvider(service=org.netbeans.spi.project.support.ant.AntBasedProjectType.class)
55
@org.openide.util.lookup.ServiceProvider(service=org.netbeans.spi.project.support.ant.AntBasedProjectType.class)
54
public final class J2SEProjectType implements AntBasedProjectType {
56
public final class J2SEProjectType implements AntBasedProjectType2 {
55
57
56
    public static final String TYPE = "org.netbeans.modules.java.j2seproject"; // NOI18N
58
    public static final String TYPE = "org.netbeans.modules.java.j2seproject"; // NOI18N
57
    private static final String PROJECT_CONFIGURATION_NAME = "data"; // NOI18N
59
    private static final String PROJECT_CONFIGURATION_NAME = "data"; // NOI18N
Lines 77-81 Link Here
77
    public String getPrimaryConfigurationDataElementNamespace(boolean shared) {
79
    public String getPrimaryConfigurationDataElementNamespace(boolean shared) {
78
        return shared ? PROJECT_CONFIGURATION_NAMESPACE : PRIVATE_CONFIGURATION_NAMESPACE;
80
        return shared ? PROJECT_CONFIGURATION_NAMESPACE : PRIVATE_CONFIGURATION_NAMESPACE;
79
    }
81
    }
82
83
    public Icon getIcon() {
84
        return ImageUtilities.image2Icon(ImageUtilities.loadImage("org/netbeans/modules/java/j2seproject/ui/resources/j2seProject.png", true));
85
    }
80
    
86
    
81
}
87
}
(-)a/maven.spring/src/org/netbeans/modules/maven/spring/layer.xml (-1 lines)
Lines 52-56 Link Here
52
            </folder>
52
            </folder>
53
        </folder>
53
        </folder>
54
    </folder>
54
    </folder>
55
56
</filesystem>
55
</filesystem>
(-)a/maven/nbproject/project.xml (-1 / +1 lines)
Lines 194-200 Link Here
194
                    <compile-dependency/>
194
                    <compile-dependency/>
195
                    <run-dependency>
195
                    <run-dependency>
196
                        <release-version>1</release-version>
196
                        <release-version>1</release-version>
197
                        <specification-version>1.18</specification-version>
197
                        <specification-version>1.22</specification-version>
198
                    </run-dependency>
198
                    </run-dependency>
199
                </dependency>
199
                </dependency>
200
                <dependency>
200
                <dependency>
(-)a/maven/src/org/netbeans/modules/maven/NbMavenProjectFactory.java (-5 / +13 lines)
Lines 43-53 Link Here
43
import java.io.File;
43
import java.io.File;
44
import java.io.IOException;
44
import java.io.IOException;
45
import org.netbeans.api.project.Project;
45
import org.netbeans.api.project.Project;
46
import org.netbeans.spi.project.ProjectFactory;
46
import org.netbeans.api.project.ProjectManager;
47
import org.netbeans.spi.project.ProjectFactory2;
47
import org.netbeans.spi.project.ProjectState;
48
import org.netbeans.spi.project.ProjectState;
48
import org.openide.ErrorManager;
49
import org.openide.ErrorManager;
49
import org.openide.filesystems.FileObject;
50
import org.openide.filesystems.FileObject;
50
import org.openide.filesystems.FileUtil;
51
import org.openide.filesystems.FileUtil;
52
import org.openide.util.ImageUtilities;
51
53
52
54
53
/**
55
/**
Lines 55-61 Link Here
55
 * @author  Milos Kleint
57
 * @author  Milos Kleint
56
 */
58
 */
57
@org.openide.util.lookup.ServiceProvider(service=org.netbeans.spi.project.ProjectFactory.class, position=666)
59
@org.openide.util.lookup.ServiceProvider(service=org.netbeans.spi.project.ProjectFactory.class, position=666)
58
public class NbMavenProjectFactory implements ProjectFactory {
60
public class NbMavenProjectFactory implements ProjectFactory2 {
59
    
61
    
60
    /** Creates a new instance of NbMavenProjectFactory */
62
    /** Creates a new instance of NbMavenProjectFactory */
61
    public NbMavenProjectFactory() {
63
    public NbMavenProjectFactory() {
Lines 76-81 Link Here
76
        }
78
        }
77
        return project.isFile() &&  !"nbproject".equalsIgnoreCase(projectDir.getName()); //NOI18N
79
        return project.isFile() &&  !"nbproject".equalsIgnoreCase(projectDir.getName()); //NOI18N
78
    }
80
    }
81
82
    public ProjectManager.Result isProject2(FileObject projectDirectory) {
83
        if (isProject(projectDirectory)) {
84
            return new ProjectManager.Result(ImageUtilities.image2Icon(ImageUtilities.loadImage("org/netbeans/modules/maven/Maven2Icon.gif", true))); //NOI18N
85
        }
86
        return null;
87
    }
88
79
    
89
    
80
    public Project loadProject(FileObject fileObject, ProjectState projectState) throws IOException
90
    public Project loadProject(FileObject fileObject, ProjectState projectState) throws IOException
81
    {
91
    {
Lines 110-116 Link Here
110
    
120
    
111
    public void saveProject(Project project) throws IOException {
121
    public void saveProject(Project project) throws IOException {
112
        // what to do here??
122
        // what to do here??
113
    }
123
    }    
114
    
115
    
116
}
124
}
(-)a/project.ant/apichanges.xml (+19 lines)
Lines 104-109 Link Here
104
    <!-- ACTUAL CHANGES BEGIN HERE: -->
104
    <!-- ACTUAL CHANGES BEGIN HERE: -->
105
105
106
    <changes>
106
    <changes>
107
        
108
        <change id="antbasedprojecttype2">
109
            <api name="general"/>
110
            <summary>Provide project icon without actually loading the project type</summary>
111
            <version major="1" minor="28"/>
112
            <date day="13" month="1" year="2009"/>
113
            <author login="mkleint"/>
114
            <compatibility addition="yes" binary="compatible" deletion="no" deprecation="no" modification="no" semantic="compatible" source="compatible"/>
115
            <description>
116
                <p>
117
                  Introducing <code>AntBasedProjectType2</code> that extends <code>AntBasedProjectType</code>
118
                  and adds <code>geticon()</code> method to allow showing the icon without actually loading the
119
                  project. Related to <code>org.netbeans.spi.project.ProjectFactory2</code> changes in the Project API module.
120
                </p>
121
            </description>
122
            <class package="org.netbeans.spi.project.support.ant" name="AntBasedProjectType2"/>
123
            <issue number="153923"/>
124
        </change>
125
        
107
        <change id="SourcesHelper-minimalSubfolders">
126
        <change id="SourcesHelper-minimalSubfolders">
108
            <api name="general"/>
127
            <api name="general"/>
109
            <summary>Added method SourcesHelper.registerExternalRoots with minimalSubfolders parameter</summary>
128
            <summary>Added method SourcesHelper.registerExternalRoots with minimalSubfolders parameter</summary>
(-)a/project.ant/nbproject/project.xml (-1 / +1 lines)
Lines 78-84 Link Here
78
                    <compile-dependency/>
78
                    <compile-dependency/>
79
                    <run-dependency>
79
                    <run-dependency>
80
                        <release-version>1</release-version>
80
                        <release-version>1</release-version>
81
                        <specification-version>1.17</specification-version>
81
                        <specification-version>1.22</specification-version>
82
                    </run-dependency>
82
                    </run-dependency>
83
                </dependency>
83
                </dependency>
84
                <dependency>
84
                <dependency>
(-)a/project.ant/src/org/netbeans/modules/project/ant/AntBasedProjectFactorySingleton.java (-1 / +47 lines)
Lines 63-71 Link Here
63
import java.util.prefs.Preferences;
63
import java.util.prefs.Preferences;
64
import java.util.zip.CRC32;
64
import java.util.zip.CRC32;
65
import org.netbeans.api.project.Project;
65
import org.netbeans.api.project.Project;
66
import org.netbeans.api.project.ProjectManager;
67
import org.netbeans.api.project.ProjectManager.Result;
66
import org.netbeans.spi.project.ProjectFactory;
68
import org.netbeans.spi.project.ProjectFactory;
69
import org.netbeans.spi.project.ProjectFactory2;
67
import org.netbeans.spi.project.ProjectState;
70
import org.netbeans.spi.project.ProjectState;
68
import org.netbeans.spi.project.support.ant.AntBasedProjectType;
71
import org.netbeans.spi.project.support.ant.AntBasedProjectType;
72
import org.netbeans.spi.project.support.ant.AntBasedProjectType2;
69
import org.netbeans.spi.project.support.ant.AntProjectHelper;
73
import org.netbeans.spi.project.support.ant.AntProjectHelper;
70
import org.openide.filesystems.FileObject;
74
import org.openide.filesystems.FileObject;
71
import org.openide.filesystems.FileUtil;
75
import org.openide.filesystems.FileUtil;
Lines 87-93 Link Here
87
 * @author Jesse Glick
91
 * @author Jesse Glick
88
 */
92
 */
89
@org.openide.util.lookup.ServiceProvider(service=org.netbeans.spi.project.ProjectFactory.class, position=100)
93
@org.openide.util.lookup.ServiceProvider(service=org.netbeans.spi.project.ProjectFactory.class, position=100)
90
public final class AntBasedProjectFactorySingleton implements ProjectFactory {
94
public final class AntBasedProjectFactorySingleton implements ProjectFactory2 {
91
    
95
    
92
    public static final String PROJECT_XML_PATH = "nbproject/project.xml"; // NOI18N
96
    public static final String PROJECT_XML_PATH = "nbproject/project.xml"; // NOI18N
93
97
Lines 159-164 Link Here
159
        File projectXmlF = new File(new File(dirF, "nbproject"), "project.xml"); // NOI18N
163
        File projectXmlF = new File(new File(dirF, "nbproject"), "project.xml"); // NOI18N
160
        return projectXmlF.isFile();
164
        return projectXmlF.isFile();
161
    }
165
    }
166
167
    public Result isProject2(FileObject projectDirectory) {
168
        if (FileUtil.toFile(projectDirectory) == null) {
169
            return null;
170
        }
171
        FileObject projectFile = projectDirectory.getFileObject(PROJECT_XML_PATH);
172
        //#54488: Added check for virtual
173
        if (projectFile == null || !projectFile.isData() || projectFile.isVirtual()) {
174
            return null;
175
        }
176
        File projectDiskFile = FileUtil.toFile(projectFile);
177
        //#63834: if projectFile exists and projectDiskFile does not, do nothing:
178
        if (projectDiskFile == null) {
179
            return null;
180
        }
181
        try {
182
            Document projectXml = loadProjectXml(projectDiskFile);
183
            if (projectXml != null) {
184
                Element typeEl = Util.findElement(projectXml.getDocumentElement(), "type", PROJECT_NS); // NOI18N
185
                if (typeEl != null) {
186
                    String type = Util.findText(typeEl);
187
                    if (type != null) {
188
                        AntBasedProjectType provider = findAntBasedProjectType(type);
189
                        if (provider != null) {
190
                            if (provider instanceof AntBasedProjectType2) {
191
                                return new ProjectManager.Result(((AntBasedProjectType2)provider).getIcon());
192
                            } else {
193
                                //put special icon?
194
                                return new ProjectManager.Result(null);
195
                            }
196
                        }
197
                    }
198
                }
199
            }
200
        } catch (IOException ex) {
201
            Logger.getLogger(AntBasedProjectFactorySingleton.class.getName()).log(Level.FINE, "Failed to load the project.xml file.", ex);
202
        }
203
        // better have false positives than false negatives (according to the ProjectManager.isProject/isProject2 javadoc.
204
        return new ProjectManager.Result(null);
205
    }
206
162
    
207
    
163
    public Project loadProject(FileObject projectDirectory, ProjectState state) throws IOException {
208
    public Project loadProject(FileObject projectDirectory, ProjectState state) throws IOException {
164
        if (FileUtil.toFile(projectDirectory) == null) {
209
        if (FileUtil.toFile(projectDirectory) == null) {
Lines 321-326 Link Here
321
        return helperRef != null ? helperRef.get() : null;
366
        return helperRef != null ? helperRef.get() : null;
322
    }
367
    }
323
368
369
324
    /**
370
    /**
325
     * Callback to create and access AntProjectHelper objects from outside its package.
371
     * Callback to create and access AntProjectHelper objects from outside its package.
326
     */
372
     */
(-)a/project.ant/src/org/netbeans/spi/project/support/ant/AntBasedProjectType2.java (+60 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
5
 *
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]"
23
 *
24
 * Contributor(s):
25
 *
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.
29
 *
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.
40
 */
41
42
package org.netbeans.spi.project.support.ant;
43
44
import javax.swing.Icon;
45
46
/**
47
 * extension of {@link org.netbeans.spi.project.support.ant.AntBasedProjectType}
48
 * that provides an icon for the project without actually creating an project instance for it.
49
 * @author mkleint
50
 * @since org.netbeans.modules.project.ant 1.28
51
 */
52
public interface AntBasedProjectType2 extends AntBasedProjectType {
53
54
    /**
55
     * icon of the project type represented by the given implementation of the interface.
56
     * @return
57
     */
58
    public Icon getIcon();
59
60
}
(-)a/projectapi/apichanges.xml (+20 lines)
Lines 104-109 Link Here
104
    <!-- ACTUAL CHANGES BEGIN HERE: -->
104
    <!-- ACTUAL CHANGES BEGIN HERE: -->
105
105
106
    <changes>
106
    <changes>
107
108
        <change id="projectfactory2">
109
            <api name="general"/>
110
            <summary>Provide project icon without actually loading the project</summary>
111
            <version major="1" minor="22"/>
112
            <date day="13" month="1" year="2009"/>
113
            <author login="mkleint"/>
114
            <compatibility addition="yes" binary="compatible" deletion="no" deprecation="no" modification="no" semantic="compatible" source="compatible"/>
115
            <description>
116
                <p>
117
                  Introducing <code>ProjectFactory2</code> that extends <code>ProjectFactory</code>
118
                  and return <code>ProjectManager.Result</code> instead of a simple boolean value.
119
                  Also add <code>ProjectManager.isProject2(FileObject)</code> method that can be used by
120
                  3rd party modules that need a fast (yet not 100% reliable) way of finding the project icon for a folder.
121
                </p>
122
            </description>
123
            <class package="org.netbeans.api.project" name="ProjectManager"/>
124
            <class package="org.netbeans.spi.project" name="ProjectFactory2"/>
125
            <issue number="153923"/>
126
        </change>
107
127
108
        <change id="lookupprovider-ann">
128
        <change id="lookupprovider-ann">
109
            <api name="general"/>
129
            <api name="general"/>
(-)a/projectapi/manifest.mf (-1 / +1 lines)
Lines 1-7 Link Here
1
Manifest-Version: 1.0
1
Manifest-Version: 1.0
2
OpenIDE-Module: org.netbeans.modules.projectapi/1
2
OpenIDE-Module: org.netbeans.modules.projectapi/1
3
OpenIDE-Module-Install: org/netbeans/modules/projectapi/Installer.class
3
OpenIDE-Module-Install: org/netbeans/modules/projectapi/Installer.class
4
OpenIDE-Module-Specification-Version: 1.21
4
OpenIDE-Module-Specification-Version: 1.22
5
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/projectapi/Bundle.properties
5
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/projectapi/Bundle.properties
6
OpenIDE-Module-Layer: org/netbeans/modules/projectapi/layer.xml
6
OpenIDE-Module-Layer: org/netbeans/modules/projectapi/layer.xml
7
7
(-)a/projectapi/src/org/netbeans/api/project/ProjectManager.java (-18 / +88 lines)
Lines 50-70 Link Here
50
import java.util.Map;
50
import java.util.Map;
51
import java.util.Set;
51
import java.util.Set;
52
import java.util.WeakHashMap;
52
import java.util.WeakHashMap;
53
import java.util.concurrent.Executor;
54
import java.util.logging.Level;
53
import java.util.logging.Level;
55
import java.util.logging.LogRecord;
54
import java.util.logging.LogRecord;
56
import java.util.logging.Logger;
55
import java.util.logging.Logger;
56
import javax.swing.Icon;
57
import org.netbeans.modules.projectapi.SimpleFileOwnerQueryImplementation;
57
import org.netbeans.modules.projectapi.SimpleFileOwnerQueryImplementation;
58
import org.netbeans.modules.projectapi.TimedWeakReference;
58
import org.netbeans.modules.projectapi.TimedWeakReference;
59
import org.netbeans.spi.project.FileOwnerQueryImplementation;
59
import org.netbeans.spi.project.FileOwnerQueryImplementation;
60
import org.netbeans.spi.project.ProjectFactory;
60
import org.netbeans.spi.project.ProjectFactory;
61
import org.netbeans.spi.project.ProjectFactory2;
61
import org.netbeans.spi.project.ProjectState;
62
import org.netbeans.spi.project.ProjectState;
62
import org.openide.filesystems.FileChangeAdapter;
63
import org.openide.filesystems.FileChangeAdapter;
63
import org.openide.filesystems.FileChangeListener;
64
import org.openide.filesystems.FileChangeListener;
64
import org.openide.filesystems.FileEvent;
65
import org.openide.filesystems.FileEvent;
65
import org.openide.filesystems.FileObject;
66
import org.openide.filesystems.FileObject;
66
import org.openide.filesystems.FileSystem;
67
import org.openide.filesystems.FileUtil;
67
import org.openide.filesystems.FileUtil;
68
import org.openide.util.ImageUtilities;
68
import org.openide.util.Lookup;
69
import org.openide.util.Lookup;
69
import org.openide.util.LookupEvent;
70
import org.openide.util.LookupEvent;
70
import org.openide.util.LookupListener;
71
import org.openide.util.LookupListener;
Lines 388-393 Link Here
388
     * @throws IllegalArgumentException if the supplied file object is null or not a folder
389
     * @throws IllegalArgumentException if the supplied file object is null or not a folder
389
     */
390
     */
390
    public boolean isProject(final FileObject projectDirectory) throws IllegalArgumentException {
391
    public boolean isProject(final FileObject projectDirectory) throws IllegalArgumentException {
392
        return isProject2(projectDirectory, false) != null;
393
    }
394
395
    /**
396
     * Check whether a given directory is likely to contain a project without
397
     * actually loading it. The returned {@link org.netbeans.api.project.ProjectManager.Result} object contains additional
398
     * information about the found project.
399
     * Should be faster and use less memory than {@link #findProject} when called
400
     * on a large number of directories.
401
     * <p>The result is not guaranteed to be accurate; there may be false positives
402
     * (directories for which <code>isProject</code> is true but {@link #findProject}
403
     * will return false), for example if there is trouble loading the project.
404
     * False negatives are possible only if there are bugs in the project factory.</p>
405
     * <p>Acquires read access.</p>
406
     * <p class="nonnormative">
407
     * You do <em>not</em> need to call this method if you just plan to call {@link #findProject}
408
     * afterwards. It is intended for only those clients which would discard the
409
     * result of {@link #findProject} other than to check for null, and which
410
     * can also tolerate false positives.
411
     * </p>
412
     * @param projectDirectory a directory which may be some project's top directory
413
     * @return Result object if the directory is likely to contain a project according to
414
     *              some registered {@link ProjectFactory}, or null if not a project folder.
415
     * @throws IllegalArgumentException if the supplied file object is null or not a folder
416
     * @since org.netbeans.modules.projectapi 1.22
417
     */
418
    public Result isProject2(final FileObject projectDirectory) throws IllegalArgumentException {
419
        return isProject2(projectDirectory, true);
420
    }
421
422
    private Result isProject2(final FileObject projectDirectory, final boolean preferResult) throws IllegalArgumentException {
391
        if (projectDirectory == null) {
423
        if (projectDirectory == null) {
392
            throw new IllegalArgumentException("Attempted to pass a null directory to isProject"); // NOI18N
424
            throw new IllegalArgumentException("Attempted to pass a null directory to isProject"); // NOI18N
393
        }
425
        }
Lines 397-407 Link Here
397
            if (projectDirectory.isValid()) {
429
            if (projectDirectory.isValid()) {
398
                throw new IllegalArgumentException("Attempted to pass a non-directory to isProject: " + projectDirectory); // NOI18N
430
                throw new IllegalArgumentException("Attempted to pass a non-directory to isProject: " + projectDirectory); // NOI18N
399
            } else {
431
            } else {
400
                return false;
432
                return null;
401
            }
433
            }
402
        }
434
        }
403
        return mutex().readAccess(new Mutex.Action<Boolean>() {
435
        return mutex().readAccess(new Mutex.Action<Result>() {
404
            public Boolean run() {
436
            public Result run() {
405
                synchronized (dir2Proj) {
437
                synchronized (dir2Proj) {
406
                    Union2<Reference<Project>,LoadStatus> o;
438
                    Union2<Reference<Project>,LoadStatus> o;
407
                    do {
439
                    do {
Lines 416-441 Link Here
416
                    } while (LoadStatus.LOADING_PROJECT.is(o));
448
                    } while (LoadStatus.LOADING_PROJECT.is(o));
417
                    assert !LoadStatus.LOADING_PROJECT.is(o);
449
                    assert !LoadStatus.LOADING_PROJECT.is(o);
418
                    if (LoadStatus.NO_SUCH_PROJECT.is(o)) {
450
                    if (LoadStatus.NO_SUCH_PROJECT.is(o)) {
419
                        return false;
451
                        return null;
420
                    } else if (o != null) {
452
                    } else if (o != null) {
421
                        // Reference<Project> or SOME_SUCH_PROJECT
453
                        // Reference<Project> or SOME_SUCH_PROJECT
422
                        return true;
454
                        // rather check for result than load project and lookup projectInformation for icon.
455
                        return checkForProject(projectDirectory, preferResult);
423
                    }
456
                    }
424
                    // Not in cache.
457
                    // Not in cache.
425
                    dir2Proj.put(projectDirectory, LoadStatus.LOADING_PROJECT.wrap());
458
                    dir2Proj.put(projectDirectory, LoadStatus.LOADING_PROJECT.wrap());
426
                }
459
                }
427
                boolean resetLP = false;
460
                boolean resetLP = false;
428
                try {
461
                try {
429
                    boolean p = checkForProject(projectDirectory);
462
                    Result p = checkForProject(projectDirectory, preferResult);
430
                    synchronized (dir2Proj) {
463
                    synchronized (dir2Proj) {
431
                        resetLP = true;
464
                        resetLP = true;
432
                        dir2Proj.notifyAll();
465
                        dir2Proj.notifyAll();
433
                        if (p) {
466
                        if (p != null) {
434
                            dir2Proj.put(projectDirectory, LoadStatus.SOME_SUCH_PROJECT.wrap());
467
                            dir2Proj.put(projectDirectory, LoadStatus.SOME_SUCH_PROJECT.wrap());
435
                            return true;
468
                            return p;
436
                        } else {
469
                        } else {
437
                            dir2Proj.put(projectDirectory, LoadStatus.NO_SUCH_PROJECT.wrap());
470
                            dir2Proj.put(projectDirectory, LoadStatus.NO_SUCH_PROJECT.wrap());
438
                            return false;
471
                            return null;
439
                        }
472
                        }
440
                    }
473
                    }
441
                } finally {
474
                } finally {
Lines 448-466 Link Here
448
            }
481
            }
449
        });
482
        });
450
    }
483
    }
451
    
484
452
    private boolean checkForProject(FileObject dir) {
485
    /**
486
     *
487
     * @param dir
488
     * @param preferResult, if false will not actually call the factory methods with populated Results, but
489
     *                      create dummy ones and use the Result as boolean flag only.
490
     * @return
491
     */
492
    private Result checkForProject(FileObject dir, boolean preferResult) {
453
        assert dir != null;
493
        assert dir != null;
454
        assert dir.isFolder() : dir;
494
        assert dir.isFolder() : dir;
455
        assert mutex().isReadAccess();
495
        assert mutex().isReadAccess();
456
        Iterator it = factories.allInstances().iterator();
496
        Iterator<? extends ProjectFactory> it = factories.allInstances().iterator();
457
        while (it.hasNext()) {
497
        while (it.hasNext()) {
458
            ProjectFactory factory = (ProjectFactory)it.next();
498
            ProjectFactory factory = it.next();
459
            if (factory.isProject(dir)) {
499
            if (factory instanceof ProjectFactory2 && preferResult) {
460
                return true;
500
                Result res = ((ProjectFactory2)factory).isProject2(dir);
501
                if (res != null) {
502
                    return res;
503
                }
504
            } else {
505
                if (factory.isProject(dir)) {
506
                    return new Result((Icon)null);
507
                }
461
            }
508
            }
462
        }
509
        }
463
        return false;
510
        return null;
464
    }
511
    }
465
    
512
    
466
    /**
513
    /**
Lines 671-675 Link Here
671
        }
718
        }
672
        
719
        
673
    }
720
    }
721
722
    /**
723
     *  A result (immutable) object returned from {@link org.netbeans.api.project.ProjectManager#isProject2} method.
724
     *  To be created by {@link org.netbeans.spi.project.ProjectFactory2} project factories.
725
     *  @since org.netbeans.modules.projectapi 1.22
726
     */
727
    public static final class Result {
728
        private Icon icon;
729
730
731
        public Result(Icon icon) {
732
            this.icon = icon;
733
        }
734
735
        /**
736
         * Get the project icon.
737
         * @return project type icon for the result or null if the icon cannot be found this way.
738
         */
739
        public Icon getIcon() {
740
            return icon;
741
        }
742
    }
743
674
    
744
    
675
}
745
}
(-)a/projectapi/src/org/netbeans/spi/project/ProjectFactory2.java (+69 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
5
 *
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]"
23
 *
24
 * If you wish your version of this file to be governed by only the CDDL
25
 * or only the GPL Version 2, indicate your decision by adding
26
 * "[Contributor] elects to include this software in this distribution
27
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
28
 * single choice of license, a recipient has the option to distribute
29
 * your version of this file under either the CDDL, the GPL Version 2 or
30
 * to extend the choice of license to its licensees as provided above.
31
 * However, if you add GPL Version 2 code and therefore, elected the GPL
32
 * Version 2 license, then the option applies only if the new code is
33
 * made subject to such option by the copyright holder.
34
 *
35
 * Contributor(s):
36
 *
37
 * Portions Copyrighted 2008 Sun Microsystems, Inc.
38
 */
39
40
package org.netbeans.spi.project;
41
42
import org.netbeans.api.project.ProjectManager;
43
import org.openide.filesystems.FileObject;
44
45
/**
46
 * Create in-memory projects from disk directories.
47
 * Instances should be registered into default lookup as ProjectFactory instances.
48
 * @author mkleint
49
 * @since org.netbeans.modules.projectapi 1.22
50
 *
51
 */
52
public interface ProjectFactory2 extends ProjectFactory {
53
54
    /**
55
     * Test whether a given directory probably refers to a project recognized by this factory
56
     * without actually trying to create it.
57
     * <p>Should be as fast as possible as it might be called sequentially on a
58
     * lot of directories.</p>
59
     * <p>Need not be definite; it is permitted to return null or throw an exception
60
     * from {@link #loadProject} even when returning <code>Result</code> instance from this
61
     * method, in case the directory looked like a project directory but in fact
62
     * had something wrong with it.</p>
63
     * <p>Will be called inside read access.</p>
64
     * @param projectDirectory a directory which might refer to a project
65
     * @return Result instance if this factory recognizes it, or null if the directory is not recognized
66
     */
67
    ProjectManager.Result isProject2(FileObject projectDirectory);
68
69
}
(-)a/projectui/src/org/netbeans/modules/project/ui/ProjectChooserAccessory.java (-3 / +22 lines)
Lines 388-393 Link Here
388
        return OpenProjectList.fileToProject( dir );
388
        return OpenProjectList.fileToProject( dir );
389
    }
389
    }
390
390
391
    private static ProjectManager.Result getProjectResult(File dir) {
392
        FileObject fo = FileUtil.toFileObject(dir);
393
        if (fo != null && /* #60518 */ fo.isFolder()) {
394
            return ProjectManager.getDefault().isProject2(fo);
395
        } else {
396
            return null;
397
        }
398
399
    }
400
391
    private void setAccessoryEnablement( boolean enable, int numberOfProjects ) {
401
    private void setAccessoryEnablement( boolean enable, int numberOfProjects ) {
392
        jLabelProjectName.setEnabled( enable );
402
        jLabelProjectName.setEnabled( enable );
393
        jTextFieldProjectName.setEnabled( enable );
403
        jTextFieldProjectName.setEnabled( enable );
Lines 606-615 Link Here
606
        }
616
        }
607
617
608
        public void run() {
618
        public void run() {
609
            Project p = OpenProjectList.fileToProject(lookingForIcon);
619
            ProjectManager.Result r = getProjectResult(lookingForIcon);
610
            Icon icon;
620
            Icon icon;
611
            if (p != null) {
621
            if (r != null) {
612
                icon = ProjectUtils.getInformation(p).getIcon();
622
                icon = r.getIcon();
623
                if (icon == null) {
624
                    Project p = getProject(lookingForIcon);
625
                    if (p != null) {
626
                        icon = ProjectUtils.getInformation(p).getIcon();
627
                    } else {
628
                        // Could also badge with an error icon:
629
                        icon = chooser.getFileSystemView().getSystemIcon(lookingForIcon);
630
                    }
631
                }
613
            } else {
632
            } else {
614
                // Could also badge with an error icon:
633
                // Could also badge with an error icon:
615
                icon = chooser.getFileSystemView().getSystemIcon(lookingForIcon);
634
                icon = chooser.getFileSystemView().getSystemIcon(lookingForIcon);
(-)a/projectui/src/org/netbeans/modules/project/ui/actions/OpenProject.java (-1 lines)
Lines 49-55 Link Here
49
import javax.swing.SwingUtilities;
49
import javax.swing.SwingUtilities;
50
import org.netbeans.api.project.FileOwnerQuery;
50
import org.netbeans.api.project.FileOwnerQuery;
51
import org.netbeans.api.project.Project;
51
import org.netbeans.api.project.Project;
52
import org.netbeans.api.project.ui.OpenProjects;
53
import org.netbeans.modules.project.ui.OpenProjectList;
52
import org.netbeans.modules.project.ui.OpenProjectList;
54
import org.netbeans.modules.project.ui.OpenProjectListSettings;
53
import org.netbeans.modules.project.ui.OpenProjectListSettings;
55
import org.netbeans.modules.project.ui.ProjectChooserAccessory;
54
import org.netbeans.modules.project.ui.ProjectChooserAccessory;
(-)a/web.project/src/org/netbeans/modules/web/project/WebProjectType.java (-2 / +8 lines)
Lines 43-56 Link Here
43
43
44
import java.io.IOException;
44
import java.io.IOException;
45
import java.util.Collection;
45
import java.util.Collection;
46
import javax.swing.Icon;
46
import org.netbeans.api.project.Project;
47
import org.netbeans.api.project.Project;
47
import org.netbeans.modules.web.project.spi.WebProjectImplementationFactory;
48
import org.netbeans.modules.web.project.spi.WebProjectImplementationFactory;
48
import org.netbeans.spi.project.support.ant.AntBasedProjectType;
49
import org.netbeans.spi.project.support.ant.AntBasedProjectType2;
49
import org.netbeans.spi.project.support.ant.AntProjectHelper;
50
import org.netbeans.spi.project.support.ant.AntProjectHelper;
51
import org.openide.util.ImageUtilities;
50
import org.openide.util.Lookup;
52
import org.openide.util.Lookup;
51
53
52
@org.openide.util.lookup.ServiceProvider(service=org.netbeans.spi.project.support.ant.AntBasedProjectType.class)
54
@org.openide.util.lookup.ServiceProvider(service=org.netbeans.spi.project.support.ant.AntBasedProjectType.class)
53
public final class WebProjectType implements AntBasedProjectType {
55
public final class WebProjectType implements AntBasedProjectType2 {
54
56
55
    public static final String TYPE = "org.netbeans.modules.web.project";
57
    public static final String TYPE = "org.netbeans.modules.web.project";
56
    private static final String PROJECT_CONFIGURATION_NAME = "data";
58
    private static final String PROJECT_CONFIGURATION_NAME = "data";
Lines 91-94 Link Here
91
    private Collection<? extends WebProjectImplementationFactory> getProjectFactories() {
93
    private Collection<? extends WebProjectImplementationFactory> getProjectFactories() {
92
        return Lookup.getDefault().lookupAll(WebProjectImplementationFactory.class);
94
        return Lookup.getDefault().lookupAll(WebProjectImplementationFactory.class);
93
    }
95
    }
96
97
    public Icon getIcon() {
98
        return ImageUtilities.image2Icon(ImageUtilities.loadImage("org/netbeans/modules/web/project/ui/resources/webProjectIcon.gif", true));
99
    }
94
}
100
}

Return to bug 153923