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 153655
Collapse All | Expand All

(-)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
(-)7814471c9767 (+110 lines)
Added 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.modules.projectapi;
41
42
import java.util.List;
43
import java.util.Set;
44
import javax.annotation.processing.Processor;
45
import javax.annotation.processing.RoundEnvironment;
46
import javax.annotation.processing.SupportedAnnotationTypes;
47
import javax.annotation.processing.SupportedSourceVersion;
48
import javax.lang.model.SourceVersion;
49
import javax.lang.model.element.Element;
50
import javax.lang.model.element.ExecutableElement;
51
import javax.lang.model.element.Modifier;
52
import javax.lang.model.element.TypeElement;
53
import javax.lang.model.element.VariableElement;
54
import javax.lang.model.util.ElementFilter;
55
import org.netbeans.spi.project.ProjectFactory;
56
import org.openide.filesystems.annotations.LayerBuilder.File;
57
import org.openide.filesystems.annotations.LayerGeneratingProcessor;
58
import org.openide.filesystems.annotations.LayerGenerationException;
59
import org.openide.util.lookup.ServiceProvider;
60
61
/** Process ProjectFactory registrations.
62
 * 
63
 * @author Jaroslav Tulach <jtulach@netbeans.org>
64
 */
65
@ServiceProvider(service=Processor.class)
66
@SupportedSourceVersion(SourceVersion.RELEASE_6)
67
@SupportedAnnotationTypes("org.netbeans.spi.project.ProjectFactory.Registration") // NOI18N
68
public class ProjectFactoryAnnotationProcessor extends LayerGeneratingProcessor {
69
70
    @Override
71
    protected boolean handleProcess(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) throws LayerGenerationException {
72
        if (roundEnv.processingOver()) {
73
            return false;
74
        }
75
        for (Element e : roundEnv.getElementsAnnotatedWith(ProjectFactory.Registration.class)) {
76
            ProjectFactory.Registration registration = e.getAnnotation(ProjectFactory.Registration.class);
77
            TypeElement clazz = (TypeElement) e;
78
            int constructorCount = 0;
79
            for (ExecutableElement constructor : ElementFilter.constructorsIn(clazz.getEnclosedElements())) {
80
                if (!constructor.getModifiers().contains(Modifier.PUBLIC)) {
81
                    continue;
82
                }
83
                List<? extends VariableElement> params = constructor.getParameters();
84
                if (params.size() == 0) {
85
                    constructorCount++;
86
                    break;
87
                }
88
                constructorCount++;
89
            }
90
            if (constructorCount == 0) {
91
                throw new LayerGenerationException("No default constructor in " + clazz); // NOI18N
92
            }
93
94
            String binName = processingEnv.getElementUtils().getBinaryName(clazz).toString();
95
            File file = layer(e).file("Services/ProjectFactories/" + binName.replace('.', '-') + ".instance"). // NOI18N
96
                methodvalue("instanceCreate", ProjectFactoryFactory.class.getName(), "create"). // NOI18N
97
                stringvalue("instanceOf", ProjectFactory.class.getName()). // NOI18N
98
                newvalue("delegate", binName); // NOI18N
99
            String[] requiredFiles = registration.requiredFiles();
100
            if (requiredFiles.length > 0) {
101
                for (int i = 0; i < requiredFiles.length; i++) {
102
                    file = file.stringvalue("file." + i, requiredFiles[i]); // NOI18N
103
                }
104
            }
105
            file.write();
106
        }
107
        return true;
108
    }
109
110
}
(-)7814471c9767 (+106 lines)
Added 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.modules.projectapi;
41
42
import java.io.IOException;
43
import java.util.Map;
44
import org.netbeans.api.project.Project;
45
import org.netbeans.spi.project.ProjectFactory;
46
import org.netbeans.spi.project.ProjectState;
47
import org.openide.filesystems.FileObject;
48
49
/** Slightly optimized factory that allows to specify important files that
50
 * need to be present for this factory to even consider loading the project.
51
 *
52
 * @author Jaroslav Tulach <jtulach@netbeans.org>
53
 */
54
public final class ProjectFactoryFactory implements ProjectFactory {
55
    private final Map map;
56
    private int max = Integer.MAX_VALUE;
57
58
    private ProjectFactoryFactory(Map map) {
59
        this.map = map;
60
    }
61
62
    public static ProjectFactory create(Map map) {
63
        return new ProjectFactoryFactory(map);
64
    }
65
66
    public void saveProject(Project project) throws IOException, ClassCastException {
67
        getDelegate().saveProject(project);
68
    }
69
70
    public Project loadProject(FileObject projectDirectory, ProjectState state) throws IOException {
71
        if (canBeProject(projectDirectory)) {
72
            return getDelegate().loadProject(projectDirectory, state);
73
        } else {
74
            return null;
75
        }
76
    }
77
78
    private boolean canBeProject(FileObject projectDirectory) {
79
        for (int i = 0; i < max; i++) {
80
            Object path = map.get("file." + i); // NOI18N
81
            if (path instanceof String) {
82
                String p = (String)path;
83
                if (projectDirectory.getFileObject(p) == null) {
84
                    return false;
85
                }
86
            } else {
87
                max = i;
88
                break;
89
            }
90
        }
91
        return true;
92
    }
93
94
    public boolean isProject(FileObject projectDirectory) {
95
        return canBeProject(projectDirectory) && getDelegate().isProject(projectDirectory);
96
    }
97
98
    /**
99
     * @return the delegate
100
     */
101
    public ProjectFactory getDelegate() {
102
        return (ProjectFactory)map.get("delegate"); // NOI18N
103
    }
104
105
106
}
(-)a/projectapi/src/org/netbeans/spi/project/ProjectFactory.java (-1 / +14 lines)
Lines 42-47 Link Here
42
package org.netbeans.spi.project;
42
package org.netbeans.spi.project;
43
43
44
import java.io.IOException;
44
import java.io.IOException;
45
import java.lang.annotation.ElementType;
46
import java.lang.annotation.Retention;
47
import java.lang.annotation.RetentionPolicy;
48
import java.lang.annotation.Target;
45
import org.netbeans.api.project.Project;
49
import org.netbeans.api.project.Project;
46
import org.openide.filesystems.FileObject;
50
import org.openide.filesystems.FileObject;
47
51
Lines 89-93 Link Here
89
     * @throws ClassCastException if this factory did not create this project
93
     * @throws ClassCastException if this factory did not create this project
90
     */
94
     */
91
    void saveProject(Project project) throws IOException, ClassCastException;
95
    void saveProject(Project project) throws IOException, ClassCastException;
92
    
96
97
    /**
98
     * annotation to register {@link ProjectFactory} instances.
99
     * @since org.netbeans.modules.projectapi 1.22
100
     */
101
    @Target(ElementType.TYPE)
102
    @Retention(RetentionPolicy.SOURCE)
103
    @interface Registration {
104
        String[] requiredFiles() default {};
105
    }
93
}
106
}
(-)7814471c9767 (+363 lines)
Added 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.api.project;
43
44
import java.io.IOException;
45
import org.netbeans.modules.projectapi.*;
46
import java.lang.ref.Reference;
47
import java.lang.ref.WeakReference;
48
import java.net.URI;
49
import java.util.Collection;
50
import org.netbeans.junit.NbTestCase;
51
import org.netbeans.spi.project.ProjectFactory;
52
import org.netbeans.spi.project.ProjectFactory.Registration;
53
import org.netbeans.spi.project.ProjectState;
54
import org.openide.filesystems.FileObject;
55
import org.openide.filesystems.FileUtil;
56
import org.openide.filesystems.test.TestFileUtils;
57
import org.openide.util.Lookup;
58
import org.openide.util.lookup.Lookups;
59
import org.openide.util.test.MockLookup;
60
61
/**
62
 * Test functionality of FileOwnerQuery.
63
 * @author Jesse Glick
64
 */
65
public class ProjectFactoryRegistrationTest extends NbTestCase {
66
    
67
    public ProjectFactoryRegistrationTest(String name) {
68
        super(name);
69
    }
70
    
71
    static {
72
        TimedWeakReference.TIMEOUT = 0;
73
    }
74
    
75
    private FileObject scratch;
76
    private FileObject projdir;
77
    private FileObject randomfile;
78
    private FileObject projfile;
79
    private FileObject projfile2;
80
    private FileObject subprojdir;
81
    private FileObject subprojfile;
82
    private FileObject hashedFile;
83
    private Project p;
84
    private FileObject zippedfile;
85
86
    protected @Override void setUp() throws Exception {
87
        DeclarativeTestFactory.active = true;
88
        MockLookup.init();
89
        Collection<? extends Object> factories = Lookups.forPath("Services").lookupAll(ProjectFactory.class);
90
        assertEquals("One is registered: " + factories, 1, factories.size());
91
        MockLookup.setInstances(factories.toArray());
92
        DeclarativeTestFactory.called = 0;
93
        
94
        ProjectManager.getDefault().reset();
95
        FileOwnerQuery.reset();
96
        scratch = TestUtil.makeScratchDir(this);
97
        projdir = scratch.createFolder("my-project");
98
        projdir.createFolder("testproject");
99
        randomfile = scratch.createData("randomfile");
100
        projfile = projdir.createData("projfile");
101
        FileObject projsubdir = projdir.createFolder("projsubdir");
102
        projfile2 = projsubdir.createData("projfile2");
103
        subprojdir = projdir.createFolder("subproject");
104
        subprojdir.createFolder("testproject");
105
        subprojfile = subprojdir.createData("subprojfile");
106
        scratch.createFolder("external1").createFolder("subdir").createData("file");
107
        scratch.createFolder("external2").createFolder("subdir").createData("file");
108
        FileObject wrongDir = scratch.createFolder("external3").createFolder("subproject").createFolder("testproject");
109
        p = ProjectManager.getDefault().findProject(wrongDir);
110
        assertNull("No project found", p);
111
        assertEquals("No calls to our factory yet", 0, DeclarativeTestFactory.called);
112
        p = ProjectManager.getDefault().findProject(projdir);
113
        assertNotNull("found a project successfully", p);
114
        assertEquals("One call to our factory", 1, DeclarativeTestFactory.called);
115
        
116
        // make jar:file:/.../projdir/foo.jar!/zipfile/zippedfile
117
        FileObject foojar = TestFileUtils.writeZipFile(projdir, "foo.jar", "zipdir/zippedfile:");
118
        FileObject foojarRoot = FileUtil.getArchiveRoot(foojar);
119
        assertNotNull("have an archive in " + foojar, foojarRoot);
120
        zippedfile = foojarRoot.getFileObject("zipdir/zippedfile");
121
        assertNotNull("zippedfile found in it", zippedfile);
122
        
123
        hashedFile = TestFileUtils.writeZipFile(projdir, ".#webapp.jar.1.45", "zipdir/zippedfile:");
124
        foojarRoot = FileUtil.getArchiveRoot(hashedFile);
125
        assertNotNull("have an archive in " + hashedFile, foojarRoot);
126
        hashedFile = foojarRoot.getFileObject("zipdir/zippedfile");
127
128
    }
129
    
130
    protected @Override void tearDown() throws Exception {
131
        scratch = null;
132
        projdir = null;
133
        randomfile = null;
134
        projfile = null;
135
        p = null;
136
    }
137
    
138
    public void testFileOwner() throws Exception {
139
        assertEquals("correct project from projfile FileObject", p, FileOwnerQuery.getOwner(projfile));
140
        URI u = FileUtil.toFile(projfile).toURI();
141
        assertEquals("correct project from projfile URI " + u, p, FileOwnerQuery.getOwner(u));
142
        assertEquals("correct project from projfile2 FileObject", p, FileOwnerQuery.getOwner(projfile2));
143
        assertEquals("correct project from projfile2 URI", p, FileOwnerQuery.getOwner(FileUtil.toFile(projfile2).toURI()));
144
        assertEquals("correct project from projdir FileObject", p, FileOwnerQuery.getOwner(projdir));
145
        assertEquals("correct project from projdir URI", p, FileOwnerQuery.getOwner(FileUtil.toFile(projdir).toURI()));
146
        // Check that it loads the project even though we have not touched it yet:
147
        Project p2 = FileOwnerQuery.getOwner(subprojfile);
148
        Project subproj = ProjectManager.getDefault().findProject(subprojdir);
149
        assertEquals("correct project from subprojdir FileObject", subproj, p2);
150
        assertEquals("correct project from subprojdir URI", subproj, FileOwnerQuery.getOwner(FileUtil.toFile(subprojdir).toURI()));
151
        assertEquals("correct project from subprojfile FileObject", subproj, FileOwnerQuery.getOwner(subprojfile));
152
        assertEquals("correct project from subprojfile URI", subproj, FileOwnerQuery.getOwner(FileUtil.toFile(subprojfile).toURI()));
153
        assertEquals("no project from randomfile FileObject", null, FileOwnerQuery.getOwner(randomfile));
154
        assertEquals("no project from randomfile URI", null, FileOwnerQuery.getOwner(FileUtil.toFile(randomfile).toURI()));
155
        assertEquals("no project in C:\\", null, FileOwnerQuery.getOwner(URI.create("file:/C:/")));
156
    }
157
    
158
    public void testJarOwners() throws Exception {
159
        assertEquals("correct owner of a ZIPped file", p, FileOwnerQuery.getOwner(zippedfile));
160
        assertEquals("correct owner of a ZIPped file URL", p, FileOwnerQuery.getOwner(URI.create(zippedfile.getURL().toExternalForm())));
161
        assertEquals("correct owner of a ZIPped file", p, FileOwnerQuery.getOwner(hashedFile));
162
        assertEquals("correct owner of a ZIPped file URL", p, FileOwnerQuery.getOwner(URI.create(hashedFile.getURL().toExternalForm())));
163
    }
164
    
165
    public void testExternalOwner() throws Exception {
166
        FileObject ext1 = scratch.getFileObject("external1");
167
        FileObject extfile1 = ext1.getFileObject("subdir/file");
168
        assertEquals("no owner yet", null, FileOwnerQuery.getOwner(extfile1));
169
        FileOwnerQuery.markExternalOwner(ext1, p, FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
170
        assertEquals("now have an owner", p, FileOwnerQuery.getOwner(extfile1));
171
        assertEquals("even for the projdir", p, FileOwnerQuery.getOwner(ext1));
172
        assertEquals("but not for something else", null, FileOwnerQuery.getOwner(scratch));
173
        FileObject ext2 = scratch.getFileObject("external2");
174
        FileObject extfile2 = ext2.getFileObject("subdir/file");
175
        assertEquals("no owner yet", null, FileOwnerQuery.getOwner(extfile2));
176
        Project p2 = ProjectManager.getDefault().findProject(subprojdir);
177
        FileOwnerQuery.markExternalOwner(ext2, p2, FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
178
        assertEquals("now have an owner", p2, FileOwnerQuery.getOwner(extfile2));
179
        assertEquals("even for the projdir", p2, FileOwnerQuery.getOwner(ext2));
180
        assertEquals("but not for something else", null, FileOwnerQuery.getOwner(scratch));
181
        assertEquals("still correct for first proj", p, FileOwnerQuery.getOwner(extfile1));
182
        FileObject ext3 = scratch.getFileObject("external3");
183
        assertEquals("no owner yet", null, FileOwnerQuery.getOwner(ext3));
184
        FileOwnerQuery.markExternalOwner(ext3, p, FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
185
        assertEquals("now have an owner", p, FileOwnerQuery.getOwner(ext3));
186
        FileObject ext3subproj = ext3.getFileObject("subproject");
187
        Project p3 = FileOwnerQuery.getOwner(ext3subproj);
188
        assertNotSame("different project", p, p3);
189
        assertEquals("but subprojects are not part of it", ProjectManager.getDefault().findProject(ext3subproj), p3);
190
        FileOwnerQuery.markExternalOwner(ext3, null, FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
191
        assertEquals("unmarking an owner works", null, FileOwnerQuery.getOwner(ext3));
192
    }
193
194
    public void testExternalOwnerFile() throws Exception {
195
        FileObject ext1 = scratch.getFileObject("external1");
196
        FileObject extfile1 = ext1.getFileObject("subdir/file");
197
        assertEquals("no owner yet", null, FileOwnerQuery.getOwner(extfile1));
198
        FileOwnerQuery.markExternalOwner(extfile1, p, FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
199
        assertEquals("now have an owner", p, FileOwnerQuery.getOwner(extfile1));
200
        assertEquals("not for the projdir", null, FileOwnerQuery.getOwner(ext1));
201
        assertEquals("and not for something else", null, FileOwnerQuery.getOwner(scratch));
202
        FileObject ext2 = scratch.getFileObject("external2");
203
        FileObject extfile2 = ext2.getFileObject("subdir/file");
204
        assertEquals("no owner yet", null, FileOwnerQuery.getOwner(extfile2));
205
        Project p2 = ProjectManager.getDefault().findProject(subprojdir);
206
        FileOwnerQuery.markExternalOwner(extfile2, p2, FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
207
        assertEquals("now have an owner", p2, FileOwnerQuery.getOwner(extfile2));
208
        assertEquals("not for the projdir", null, FileOwnerQuery.getOwner(ext2));
209
        assertEquals("and not for something else", null, FileOwnerQuery.getOwner(scratch));
210
        assertEquals("still correct for first proj", p, FileOwnerQuery.getOwner(extfile1));
211
        
212
        //XXX: unmarking files.
213
    }
214
    
215
    public void testExternalOwnerURI() throws Exception {
216
        FileObject ext1 = scratch.getFileObject("external1");
217
        FileObject extfile1 = ext1.getFileObject("subdir/file");
218
        assertEquals("no owner yet through FileObjects", null, FileOwnerQuery.getOwner(extfile1));
219
        assertEquals("no owner yet through URI", null, FileOwnerQuery.getOwner(extfile1));
220
        FileOwnerQuery.markExternalOwner(fileObject2URI(ext1), p, FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
221
        assertEquals("now have an owner through FileObjects", p, FileOwnerQuery.getOwner(extfile1));
222
        assertEquals("now have an owner through URI", p, FileOwnerQuery.getOwner(fileObject2URI(extfile1)));
223
        assertEquals("even for the projdir throught FileObjects", p, FileOwnerQuery.getOwner(ext1));
224
        assertEquals("even for the projdir throught URI", p, FileOwnerQuery.getOwner(fileObject2URI(ext1)));
225
        assertEquals("but not for something else throught FileObjects", null, FileOwnerQuery.getOwner(scratch));
226
        assertEquals("but not for something else throught URI", null, FileOwnerQuery.getOwner(fileObject2URI(scratch)));
227
        FileObject ext2 = scratch.getFileObject("external2");
228
        FileObject extfile2 = ext2.getFileObject("subdir/file");
229
        assertEquals("no owner yet through FileObjects", null, FileOwnerQuery.getOwner(extfile2));
230
        assertEquals("no owner yet through URI", null, FileOwnerQuery.getOwner(fileObject2URI(extfile2)));
231
        Project p2 = ProjectManager.getDefault().findProject(subprojdir);
232
        FileOwnerQuery.markExternalOwner(fileObject2URI(ext2), p2, FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
233
        assertEquals("now have an owner through FileObjects", p2, FileOwnerQuery.getOwner(extfile2));
234
        assertEquals("now have an owner through URI", p2, FileOwnerQuery.getOwner(fileObject2URI(extfile2)));
235
        assertEquals("even for the projdir through FileObjects", p2, FileOwnerQuery.getOwner(ext2));
236
        assertEquals("even for the projdir through URI", p2, FileOwnerQuery.getOwner(ext2));
237
        assertEquals("but not for something else through FileObjects", null, FileOwnerQuery.getOwner(scratch));
238
        assertEquals("but not for something else through URI", null, FileOwnerQuery.getOwner(fileObject2URI(scratch)));
239
        assertEquals("still correct for first proj through FileObjects", p, FileOwnerQuery.getOwner(extfile1));
240
        assertEquals("still correct for first proj through URI", p, FileOwnerQuery.getOwner(fileObject2URI(extfile1)));
241
        FileObject ext3 = scratch.getFileObject("external3");
242
        assertEquals("no owner yet through FileObjects", null, FileOwnerQuery.getOwner(ext3));
243
        assertEquals("no owner yet through URI", null, FileOwnerQuery.getOwner(fileObject2URI(ext3)));
244
        FileOwnerQuery.markExternalOwner(fileObject2URI(ext3), p, FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
245
        assertEquals("now have an owner through FileObjects", p, FileOwnerQuery.getOwner(ext3));
246
        assertEquals("now have an owner through URI", p, FileOwnerQuery.getOwner(fileObject2URI(ext3)));
247
        FileObject ext3subproj = ext3.getFileObject("subproject");
248
        Project p3 = FileOwnerQuery.getOwner(ext3subproj);
249
        assertNotSame("different project", p, p3);
250
        assertEquals("but subprojects are not part of it", ProjectManager.getDefault().findProject(ext3subproj), p3);
251
        FileOwnerQuery.markExternalOwner(fileObject2URI(ext3), null, FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
252
        assertEquals("unmarking an owner works through FileObjects", null, FileOwnerQuery.getOwner(ext3));
253
        assertEquals("unmarking an owner works through URI", null, FileOwnerQuery.getOwner(fileObject2URI(ext3)));
254
    }
255
    
256
    public void testExternalOwnerFileURI() throws Exception {
257
        FileObject ext1 = scratch.getFileObject("external1");
258
        FileObject extfile1 = ext1.getFileObject("subdir/file");
259
        assertEquals("no owner yet through FileObjects", null, FileOwnerQuery.getOwner(extfile1));
260
        assertEquals("no owner yet through URI", null, FileOwnerQuery.getOwner(fileObject2URI(extfile1)));
261
        FileOwnerQuery.markExternalOwner(fileObject2URI(extfile1), p, FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
262
        assertEquals("now have an owner through FileObjects", p, FileOwnerQuery.getOwner(extfile1));
263
        assertEquals("now have an owner through URI", p, FileOwnerQuery.getOwner(fileObject2URI(extfile1)));
264
        assertEquals("not for the projdir through FileObjects", null, FileOwnerQuery.getOwner(ext1));
265
        assertEquals("not for the projdir through URI", null, FileOwnerQuery.getOwner(fileObject2URI(ext1)));
266
        assertEquals("and not for something else through FileObjects", null, FileOwnerQuery.getOwner(scratch));
267
        assertEquals("and not for something else through URI", null, FileOwnerQuery.getOwner(fileObject2URI(scratch)));
268
        FileObject ext2 = scratch.getFileObject("external2");
269
        FileObject extfile2 = ext2.getFileObject("subdir/file");
270
        assertEquals("no owner yet through FileObjects", null, FileOwnerQuery.getOwner(extfile2));
271
        assertEquals("no owner yet through URI", null, FileOwnerQuery.getOwner(fileObject2URI(extfile2)));
272
        Project p2 = ProjectManager.getDefault().findProject(subprojdir);
273
        FileOwnerQuery.markExternalOwner(fileObject2URI(extfile2), p2, FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
274
        assertEquals("now have an owner through FileObjects", p2, FileOwnerQuery.getOwner(extfile2));
275
        assertEquals("now have an owner through URI", p2, FileOwnerQuery.getOwner(fileObject2URI(extfile2)));
276
        assertEquals("not for the projdir through FileObjects", null, FileOwnerQuery.getOwner(ext2));
277
        assertEquals("not for the projdir through URI", null, FileOwnerQuery.getOwner(fileObject2URI(ext2)));
278
        assertEquals("and not for something else through FileObjects", null, FileOwnerQuery.getOwner(scratch));
279
        assertEquals("and not for something else through URI", null, FileOwnerQuery.getOwner(fileObject2URI(scratch)));
280
        assertEquals("still correct for first proj through FileObjects", p, FileOwnerQuery.getOwner(extfile1));
281
        assertEquals("still correct for first proj through URI", p, FileOwnerQuery.getOwner(fileObject2URI(extfile1)));
282
        
283
        //XXX: unmarking files.
284
    }
285
    
286
    public void testIsProjectDirCollectible() throws Exception {
287
        Project p2 = ProjectManager.getDefault().findProject(subprojdir);
288
        FileObject root = p2.getProjectDirectory();
289
        FileObject ext2 = scratch.getFileObject("external2");
290
        FileObject extfile2 = ext2.getFileObject("subdir/file");
291
        
292
        FileOwnerQuery.markExternalOwner(fileObject2URI(extfile2), p2, FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
293
        
294
        Reference<?> p2WR = new WeakReference<Object>(p2);
295
        Reference<?> rootWR = new WeakReference<Object>(root);
296
        
297
        p2 = null;
298
        root = null;
299
        ext2 = null;
300
        extfile2 = null;
301
        subprojdir = null;
302
        subprojfile = null;
303
        
304
        assertGC("project 2 collected", p2WR);
305
        assertGC("project 2's project dir collected", rootWR);
306
    }
307
    
308
    
309
    /**
310
     * Tests the issue 60297. GC causes previosly registered extenral roots
311
     * for project to be released. Only one extenral root per project is kept.
312
     *
313
     */
314
    public void testIssue60297 () throws Exception {
315
        FileObject ext1 = scratch.getFileObject("external1");                
316
        assertEquals("no owner yet", null, FileOwnerQuery.getOwner(ext1));
317
        FileOwnerQuery.markExternalOwner(ext1, p, FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
318
        assertEquals("now have an owner", p, FileOwnerQuery.getOwner(ext1));        
319
        FileObject ext2 = scratch.getFileObject("external2");
320
        assertEquals("no owner yet", null, FileOwnerQuery.getOwner(ext2));
321
        FileOwnerQuery.markExternalOwner(ext2, p, FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
322
        System.gc();
323
        assertEquals("now have an owner", p, FileOwnerQuery.getOwner(ext2));        
324
        assertEquals("still correct for the first external root", p, FileOwnerQuery.getOwner(ext1));
325
    }
326
    
327
    private static URI fileObject2URI(FileObject f) throws Exception {
328
        return URI.create(f.getURL().toString());
329
    }
330
    
331
332
    @Registration(requiredFiles="testproject")
333
    public static final class DeclarativeTestFactory extends TestUtil.TestProjectFactory {
334
        static boolean active;
335
        static int called;
336
337
        @Override
338
        public boolean isProject(FileObject dir) {
339
            if (!active) {
340
                return false;
341
            }
342
            called++;
343
            return super.isProject(dir);
344
        }
345
346
        @Override
347
        public Project loadProject(FileObject projectDirectory, ProjectState state) throws IOException {
348
            if (!active) {
349
                return null;
350
            }
351
            called++;
352
            return super.loadProject(projectDirectory, state);
353
        }
354
355
        @Override
356
        public void saveProject(Project project) throws IOException, ClassCastException {
357
            if (active) {
358
                super.saveProject(project);
359
            }
360
        }
361
362
    }
363
}
(-)a/projectapi/test/unit/src/org/netbeans/api/project/TestUtil.java (-1 / +1 lines)
Lines 190-196 Link Here
190
     */
190
     */
191
    public static Lookup LOOKUP = null;
191
    public static Lookup LOOKUP = null;
192
    
192
    
193
    private static final class TestProjectFactory implements ProjectFactory {
193
    static class TestProjectFactory implements ProjectFactory {
194
        
194
        
195
        TestProjectFactory() {}
195
        TestProjectFactory() {}
196
        
196
        

Return to bug 153655