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

(-)9db4e8ed858b (+144 lines)
Added Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2010 Sun Microsystems, Inc.
41
 */
42
43
package org.netbeans.modules.projectapi;
44
45
import java.io.IOException;
46
import java.lang.reflect.Method;
47
import java.util.ArrayList;
48
import java.util.List;
49
import org.netbeans.api.project.Project;
50
import org.netbeans.api.project.ProjectManager.Result;
51
import org.netbeans.spi.project.ProjectFactory2;
52
import org.netbeans.spi.project.ProjectState;
53
import org.openide.filesystems.FileObject;
54
import org.openide.util.ImageUtilities;
55
import org.openide.util.Lookup;
56
57
/**
58
 *
59
 * @author Jaroslav Tulach <jtulach@netbeans.org>
60
 */
61
public final class GenericProjectFactory implements ProjectFactory2 {
62
    private final String mimeType;
63
    private final List<String> relativeFiles;
64
    private final String iconBase;
65
    private final String clazz;
66
    private final String method;
67
68
    private GenericProjectFactory(
69
        String mimeType, List<String> relativeFiles, String iconBase,
70
        String clazz, String method
71
    ) {
72
        this.mimeType = mimeType;
73
        this.relativeFiles = relativeFiles;
74
        this.iconBase = iconBase;
75
        this.clazz = clazz;
76
        this.method = method;
77
    }
78
    
79
    public static GenericProjectFactory create(FileObject fo) {
80
        List<String> arr = new ArrayList<String>();
81
        for (int cnt = 0; ; cnt++) {
82
            Object attr = fo.getAttribute("relativeFile." + cnt);
83
            if (attr instanceof String) {
84
                arr.add((String)attr);
85
            } else {
86
                break;
87
            }
88
        }
89
        return new GenericProjectFactory(
90
            (String)fo.getAttribute("mimeType"),
91
            arr,
92
            (String)fo.getAttribute("iconBase"),
93
            (String)fo.getAttribute("class"),
94
            (String)fo.getAttribute("method")
95
        );
96
    }
97
    
98
    @Override
99
    public Result isProject2(FileObject projectDirectory) {
100
        if (isProject(projectDirectory)) {
101
            return new Result(ImageUtilities.loadImageIcon(iconBase, true));
102
        }
103
        return null;
104
    }
105
106
    @Override
107
    public boolean isProject(FileObject projectDirectory) {
108
        for (String rp: relativeFiles) {
109
            FileObject fo = projectDirectory.getFileObject(rp);
110
            if (fo == null) {
111
                continue;
112
            }
113
            if (mimeType != null && !mimeType.equals(fo.getMIMEType())) {
114
                continue;
115
            }
116
            return true;
117
        }
118
        return false;
119
    }
120
121
    @Override
122
    public Project loadProject(FileObject projectDirectory, ProjectState state) throws IOException {
123
        ClassLoader l = Lookup.getDefault().lookup(ClassLoader.class);
124
        if (l == null) {
125
            l = Thread.currentThread().getContextClassLoader();
126
        }
127
        if (l == null) {
128
            l = GenericProjectFactory.class.getClassLoader();
129
        }
130
        try {
131
            Class<?> real = Class.forName(this.clazz, true, l);
132
            Method m = real.getMethod(method, FileObject.class);
133
            return (Project) m.invoke(null, projectDirectory);
134
        } catch (Exception ex) {
135
            throw new IOException(ex);
136
        }
137
    }
138
139
    @Override
140
    public void saveProject(Project project) throws IOException, ClassCastException {
141
        throw new UnsupportedOperationException("Not supported yet.");
142
    }
143
144
}
(-)9db4e8ed858b (+121 lines)
Added Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2010 Sun Microsystems, Inc.
41
 */
42
43
package org.netbeans.modules.projectapi;
44
45
import java.util.List;
46
import java.util.Set;
47
import javax.annotation.processing.Processor;
48
import javax.annotation.processing.RoundEnvironment;
49
import javax.annotation.processing.SupportedAnnotationTypes;
50
import javax.annotation.processing.SupportedSourceVersion;
51
import javax.lang.model.SourceVersion;
52
import javax.lang.model.element.Element;
53
import javax.lang.model.element.ExecutableElement;
54
import javax.lang.model.element.Modifier;
55
import javax.lang.model.element.TypeElement;
56
import javax.lang.model.element.VariableElement;
57
import javax.lang.model.type.TypeMirror;
58
import org.netbeans.api.project.Project;
59
import org.netbeans.spi.project.ProjectRegistration;
60
import org.openide.filesystems.FileObject;
61
import org.openide.filesystems.annotations.LayerBuilder.File;
62
import org.openide.filesystems.annotations.LayerGeneratingProcessor;
63
import org.openide.filesystems.annotations.LayerGenerationException;
64
import org.openide.util.lookup.ServiceProvider;
65
66
/**
67
 *
68
 * @author Jaroslav Tulach <jtulach@netbeans.org>
69
 */
70
@SupportedAnnotationTypes("org.netbeans.spi.project.ProjectRegistration")
71
@SupportedSourceVersion(SourceVersion.RELEASE_6)
72
@ServiceProvider(service=Processor.class)
73
public final class GenericProjectProcessor extends LayerGeneratingProcessor {
74
    @Override
75
    protected boolean handleProcess(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) throws LayerGenerationException {
76
        for (Element e : roundEnv.getElementsAnnotatedWith(ProjectRegistration.class)) {
77
            ProjectRegistration pr = e.getAnnotation(ProjectRegistration.class);
78
            String[] param = getMethod(e);
79
            File f = layer(e).file("Services/ProjectFactories/" +
80
                param[0].replace('.', '-') + "-" + param[1] + ".instance"
81
            );
82
            f.methodvalue("instanceCreate", GenericProjectFactory.class.getName(), "create");
83
            if (pr.mimeType().length() > 0) {
84
                f.stringvalue("mimeType", pr.mimeType());
85
            }
86
            f.stringvalue("iconBase", pr.iconBase());
87
            int cnt = 0;
88
            for (String p : pr.relativeFile()) {
89
                f.stringvalue("relativeFile." + cnt++, p);
90
            }
91
            f.stringvalue("class", param[0]);
92
            f.stringvalue("method", param[1]);
93
            f.write();
94
        }
95
        return true;
96
    }
97
98
    private String[] getMethod(Element originatingElement) throws LayerGenerationException {
99
        TypeMirror projectMirror = processingEnv.getTypeUtils().getDeclaredType(
100
            processingEnv.getElementUtils().getTypeElement(Project.class.getName())
101
        );
102
        TypeMirror foMirror = processingEnv.getTypeUtils().getDeclaredType(
103
            processingEnv.getElementUtils().getTypeElement(FileObject.class.getName())
104
        );
105
        String clazz = processingEnv.getElementUtils().getBinaryName((TypeElement) originatingElement.getEnclosingElement()).toString();
106
        String method = originatingElement.getSimpleName().toString();
107
        if (!originatingElement.getModifiers().contains(Modifier.STATIC)) {
108
            throw new LayerGenerationException(clazz + "." + method + " must be static", originatingElement);
109
        }
110
        final List<? extends VariableElement> params = ((ExecutableElement) originatingElement).getParameters();
111
        boolean sameType = processingEnv.getTypeUtils().isSameType(params.get(0).asType(), foMirror);
112
        if (params.size() != 1 || !sameType) {
113
            throw new LayerGenerationException(clazz + "." + method + " must take org.openide.filesystems.FileObject agrument", originatingElement);
114
        }
115
        if (projectMirror != null && !processingEnv.getTypeUtils().isAssignable(((ExecutableElement) originatingElement).getReturnType(), projectMirror)) {
116
            throw new LayerGenerationException(clazz + "." + method + " is not assignable to " + projectMirror, originatingElement);
117
        }
118
        return new String[] {clazz, method};
119
    }
120
    
121
}
(-)9db4e8ed858b (+85 lines)
Added Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2010 Sun Microsystems, Inc.
41
 */
42
43
package org.netbeans.spi.project;
44
45
import java.io.IOException;
46
import java.lang.annotation.ElementType;
47
import java.lang.annotation.Retention;
48
import java.lang.annotation.RetentionPolicy;
49
import java.lang.annotation.Target;
50
import org.netbeans.api.project.Project;
51
import org.openide.filesystems.FileObject;
52
import org.openide.filesystems.MIMEResolver;
53
54
/** Annotate static factory method that converts
55
 * {@link FileObject} to {@link Project} (the method
56
 * can return null and also thrown an {@link IOException}).
57
 *
58
 * @author Jaroslav Tulach <jtulach@netbeans.org>
59
 * @since 1.35
60
 */
61
@Retention(RetentionPolicy.SOURCE)
62
@Target(ElementType.METHOD)
63
public @interface ProjectRegistration {
64
    /** Path to icon that represents the project produced
65
     * by this factory method.
66
     * @return icon path
67
     */
68
    String iconBase();
69
    
70
    /** File or list of relative files to check for. At least one
71
     * of these files must be present and must have appropriate 
72
     * {@link #mimeType} (if specified).
73
     * 
74
     * @return relative paths separated by '/'
75
     */ 
76
    String[] relativeFile();
77
    /** The mime type of one of the relative files. By specifying
78
     * the mime type you can also check inside of the {@link #relativeFile relative files}.
79
     * See {@link MIMEResolver} for a way to specify mime type based
80
     * on content of a file.
81
     * @return required mime type
82
     */
83
    String mimeType() default "";
84
}
85
(-)9db4e8ed858b (+131 lines)
Added Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2010 Sun Microsystems, Inc.
41
 */
42
43
package org.netbeans.spi.project;
44
45
import java.io.IOException;
46
import java.util.Collection;
47
import org.netbeans.api.project.Project;
48
import org.netbeans.api.project.ProjectManager;
49
import org.netbeans.api.project.ProjectManager.Result;
50
import org.netbeans.junit.NbTestCase;
51
import org.netbeans.modules.projectapi.GenericProjectFactory;
52
import org.openide.filesystems.FileObject;
53
import org.openide.filesystems.FileUtil;
54
import org.openide.util.ImageUtilities;
55
import org.openide.util.Lookup;
56
import org.openide.util.lookup.Lookups;
57
import org.openide.util.test.MockLookup;
58
59
public class ProjectRegistrationTest extends NbTestCase {
60
    static {
61
        FileUtil.setMIMEType("tu", "application/x-jarda");
62
    }
63
    static int cnt;
64
65
    public ProjectRegistrationTest(String name) {
66
        super(name);
67
    }
68
69
    @Override
70
    protected void setUp() throws Exception {
71
        super.setUp();
72
        MockLookup.init();
73
        MockLookup.setLookup(
74
            Lookups.singleton(ProjectRegistrationTest.class.getClassLoader()), 
75
            Lookups.forPath("Services/ProjectFactories")
76
        );
77
        Collection<? extends ProjectFactory> all2 = Lookup.getDefault().lookupAll(ProjectFactory.class);
78
        assertEquals("One ", 1, all2.size());
79
        assertTrue(all2.iterator().next() instanceof GenericProjectFactory);
80
    }
81
    
82
    
83
84
    @ProjectRegistration(
85
        iconBase="org/netbeans/api/project/resources/icon-1.png",
86
        relativeFile="jar/da.tu"
87
    )
88
    public static Project recognize(FileObject fo) throws IOException {
89
        cnt++;
90
        return new MyPrj(fo);
91
    }
92
    
93
    public void testRegognize() throws IOException {
94
        FileObject root = FileUtil.createMemoryFileSystem().getRoot();
95
        FileObject tu = FileUtil.createData(root, "my/x/jar/da.tu");
96
        FileObject jar = tu.getParent();
97
        FileObject x = jar.getParent();
98
        
99
        assertFalse("Not a project", ProjectManager.getDefault().isProject(jar));
100
        assertTrue("Possibly a project", ProjectManager.getDefault().isProject(x));
101
        assertEquals("No calls to factory yet", 0, cnt);
102
        Result res = ProjectManager.getDefault().isProject2(x);
103
        assertEquals("The same icon", 
104
            res.getIcon(), 
105
            ImageUtilities.loadImageIcon("org/netbeans/api/project/resources/icon-1.png", true)
106
        );
107
        Project p = ProjectManager.getDefault().findProject(x);
108
        assertNotNull("Project really created");
109
        assertEquals("One call to factory", 1, cnt);
110
        assertEquals("The right type", MyPrj.class, p.getClass());
111
    }
112
    
113
    private static class MyPrj implements Project {
114
        private final FileObject prj;
115
116
        public MyPrj(FileObject prj) {
117
            this.prj = prj;
118
        }
119
        
120
        @Override
121
        public FileObject getProjectDirectory() {
122
            return prj;
123
        }
124
125
        @Override
126
        public Lookup getLookup() {
127
            return Lookup.EMPTY;
128
        }
129
        
130
    }
131
}

Return to bug 193549