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

(-)a/projectuiapi.base/apichanges.xml (+16 lines)
Lines 107-112 Link Here
107
    <!-- ACTUAL CHANGES BEGIN HERE: -->
107
    <!-- ACTUAL CHANGES BEGIN HERE: -->
108
108
109
    <changes>
109
    <changes>
110
        <change id="ProjectConvertors-lookup">
111
            <api name="BaseProjectUIAPI"/>
112
            <summary>Added support methods into <code>ProjectConvertors</code> for easier convertor project implementation.</summary>
113
            <version major="1" minor="82"/>
114
            <date day="21" month="7" year="2015"/>
115
            <author login="tzezula"/>
116
            <compatibility addition="yes"/>
117
            <description>
118
                <p>
119
                    Added support methods into the <code>ProjectConvertors</code> for easier <code>ProjectConvertor</code> lookup
120
                    and queries implementation.
121
                </p>
122
            </description>
123
            <class package="org.netbeans.spi.project.ui.support" name="ProjectConvertors"/>
124
            <issue number="253338"/>
125
        </change>
110
        <change id="ProjectConvertors-unregister">
126
        <change id="ProjectConvertors-unregister">
111
            <api name="BaseProjectUIAPI"/>
127
            <api name="BaseProjectUIAPI"/>
112
            <summary>Added <code>unregisterConvertorProject</code>into <code>ProjectConvertors</code>.</summary>
128
            <summary>Added <code>unregisterConvertorProject</code>into <code>ProjectConvertors</code>.</summary>
(-)a/projectuiapi.base/nbproject/project.properties (-1 / +1 lines)
Lines 42-48 Link Here
42
42
43
javac.compilerargs=-Xlint -Xlint:-serial
43
javac.compilerargs=-Xlint -Xlint:-serial
44
javac.source=1.7
44
javac.source=1.7
45
spec.version.base=1.81.0
45
spec.version.base=1.82.0
46
is.autoload=true
46
is.autoload=true
47
javadoc.arch=${basedir}/arch.xml
47
javadoc.arch=${basedir}/arch.xml
48
javadoc.apichanges=${basedir}/apichanges.xml
48
javadoc.apichanges=${basedir}/apichanges.xml
(-)a/projectuiapi.base/src/org/netbeans/spi/project/ui/support/ProjectConvertors.java (+84 lines)
Lines 41-51 Link Here
41
 */
41
 */
42
package org.netbeans.spi.project.ui.support;
42
package org.netbeans.spi.project.ui.support;
43
43
44
import java.io.Closeable;
45
import java.io.IOException;
46
import java.nio.charset.Charset;
47
import org.netbeans.api.annotations.common.CheckForNull;
44
import org.netbeans.api.annotations.common.NonNull;
48
import org.netbeans.api.annotations.common.NonNull;
49
import org.netbeans.api.project.FileOwnerQuery;
45
import org.netbeans.api.project.Project;
50
import org.netbeans.api.project.Project;
46
import org.netbeans.api.project.ProjectManager;
51
import org.netbeans.api.project.ProjectManager;
47
import org.netbeans.modules.project.ui.convertor.ProjectConvertorFactory;
52
import org.netbeans.modules.project.ui.convertor.ProjectConvertorFactory;
48
import org.netbeans.spi.project.ui.ProjectConvertor;
53
import org.netbeans.spi.project.ui.ProjectConvertor;
54
import org.netbeans.spi.queries.FileEncodingQueryImplementation;
55
import org.openide.filesystems.FileObject;
56
import org.openide.util.Lookup;
57
import org.openide.util.lookup.Lookups;
58
import org.openide.util.lookup.ProxyLookup;
49
59
50
/**
60
/**
51
 * Support for {@link ProjectConvertor}s.
61
 * Support for {@link ProjectConvertor}s.
Lines 78-81 Link Here
78
    public static void unregisterConvertorProject(@NonNull final Project project) {
88
    public static void unregisterConvertorProject(@NonNull final Project project) {
79
        ProjectConvertorFactory.unregisterConvertorProject(project);
89
        ProjectConvertorFactory.unregisterConvertorProject(project);
80
    }
90
    }
91
92
    /**
93
     * Finds the owning non convertor project.
94
     * Finds nearest enclosing non convertor project.
95
     * @param file the {@link FileObject} to find owner for
96
     * @return the owning {@link Project} or null if there is no such a project.
97
     * @since 1.82
98
     */
99
    @CheckForNull
100
    @SuppressWarnings("NestedAssignment")
101
    public static Project getNonConvertorOwner(@NonNull final FileObject file) {
102
        for (FileObject parent = file.getParent(); parent != null; parent = parent.getParent()) {
103
            final Project prj = FileOwnerQuery.getOwner(parent);
104
            if (prj != null && !isConvertorProject(prj)) {
105
                return prj;
106
            }
107
        }
108
        return null;
109
    }
110
111
    /**
112
     * Creates {@link FileEncodingQueryImplementation} delegating to the nearest non convertor project.
113
     * @return the {@link FileEncodingQueryImplementation}
114
     * @since 1.82
115
     */
116
    @NonNull
117
    public static FileEncodingQueryImplementation createFileEncodingQuery() {
118
        return new ConvertorFileEncodingQuery();
119
    }
120
121
    /**
122
     * Creates a {@link Lookup} with given instances.
123
     * The returned {@link Lookup} implements {@link Closeable}, calling {@link Closeable#close}
124
     * on it removes all the instances.
125
     * <p class="nonnormative">
126
     * Typical usage would be to pass the {@link Lookup} to {@link ProjectConvertor.Result#Result}
127
     * and call {@link Closeable#close} on it in the convertor's project factory before the real
128
     * project is created.
129
     * </p>
130
     * @param instances the {@link Lookup} content
131
     * @return the {@link Lookup} implementing {@link Closeable}
132
     * @since 1.82
133
     */
134
    @NonNull
135
    public static Lookup createProjectConvertorLookup(@NonNull final Object... instances) {
136
        return new CloseableLookup(instances);
137
    }
138
139
    private static final class ConvertorFileEncodingQuery extends FileEncodingQueryImplementation {
140
141
        ConvertorFileEncodingQuery() {}
142
143
        @Override
144
        @CheckForNull
145
        public Charset getEncoding(@NonNull final FileObject file) {
146
            final Project p = getNonConvertorOwner(file);
147
            return p != null ?
148
                p.getLookup().lookup(FileEncodingQueryImplementation.class).getEncoding(file) :
149
                null;
150
        }
151
    }
152
153
    private static final class CloseableLookup extends ProxyLookup implements Closeable {
154
155
        CloseableLookup(Object... instances) {
156
            setLookups(Lookups.fixed(instances));
157
        }
158
159
        @Override
160
        public void close() throws IOException {
161
            setLookups(Lookup.EMPTY);
162
        }
163
    }
164
81
}
165
}
(-)a/projectuiapi.base/test/unit/src/org/netbeans/modules/project/ui/ProjectConvertorFactoryTest.java (-13 / +9 lines)
Lines 42-47 Link Here
42
package org.netbeans.modules.project.ui;
42
package org.netbeans.modules.project.ui;
43
43
44
import java.beans.PropertyChangeListener;
44
import java.beans.PropertyChangeListener;
45
import java.io.Closeable;
45
import java.io.File;
46
import java.io.File;
46
import java.io.IOException;
47
import java.io.IOException;
47
import java.util.concurrent.Callable;
48
import java.util.concurrent.Callable;
Lines 53-58 Link Here
53
import org.netbeans.api.project.ui.OpenProjects;
54
import org.netbeans.api.project.ui.OpenProjects;
54
import org.netbeans.junit.NbTestCase;
55
import org.netbeans.junit.NbTestCase;
55
import org.netbeans.modules.project.ui.convertor.ProjectConvertorFactory;
56
import org.netbeans.modules.project.ui.convertor.ProjectConvertorFactory;
57
import org.netbeans.spi.project.ui.support.ProjectConvertors;
56
import org.openide.filesystems.FileObject;
58
import org.openide.filesystems.FileObject;
57
import org.openide.filesystems.FileUtil;
59
import org.openide.filesystems.FileUtil;
58
import org.openide.util.Lookup;
60
import org.openide.util.Lookup;
Lines 98-105 Link Here
98
            }
100
            }
99
        };
101
        };
100
        final Lookup clp = Lookups.singleton(new ConvertorAdditionalServicePermanent());
102
        final Lookup clp = Lookups.singleton(new ConvertorAdditionalServicePermanent());
101
        final Lookup clt = Lookups.singleton(new ConvertorAdditionalServiceTransient());
103
        final Lookup clt = ProjectConvertors.createProjectConvertorLookup(new ConvertorAdditionalServiceTransient());
102
        final PL cl = new PL(clp, clt);
104
        final Lookup cl = new ProxyLookup(clp, clt);
103
        TestProject.Convertor.LOOKUP_FACTORY = new Callable<Lookup>() {
105
        TestProject.Convertor.LOOKUP_FACTORY = new Callable<Lookup>() {
104
            @Override
106
            @Override
105
            public Lookup call() throws Exception {
107
            public Lookup call() throws Exception {
Lines 109-115 Link Here
109
        TestProject.Convertor.CALLBACK = new Runnable() {
111
        TestProject.Convertor.CALLBACK = new Runnable() {
110
            @Override
112
            @Override
111
            public void run() {
113
            public void run() {
112
                cl.update(clp);
114
                try {
115
                    ((Closeable)clt).close();
116
                } catch (IOException ioe) {
117
                    throw new RuntimeException(ioe);
118
                }
113
            }
119
            }
114
        };
120
        };
115
        final Project artPrj = ProjectManager.getDefault().findProject(projectDir);
121
        final Project artPrj = ProjectManager.getDefault().findProject(projectDir);
Lines 260-273 Link Here
260
        public void removePropertyChangeListener(PropertyChangeListener listener) {
266
        public void removePropertyChangeListener(PropertyChangeListener listener) {
261
        }
267
        }
262
    }
268
    }
263
264
    private static final class PL extends ProxyLookup {
265
        PL(@NonNull final Lookup... lkps) {
266
            super(lkps);
267
        }
268
269
        void update(@NonNull final Lookup... lkps) {
270
            setLookups(lkps);
271
        }
272
    }
273
}
269
}
(-)a/web.clientproject/nbproject/project.xml (-1 / +1 lines)
Lines 168-174 Link Here
168
                    <compile-dependency/>
168
                    <compile-dependency/>
169
                    <run-dependency>
169
                    <run-dependency>
170
                        <release-version>1</release-version>
170
                        <release-version>1</release-version>
171
                        <specification-version>1.80</specification-version>
171
                        <specification-version>1.82</specification-version>
172
                    </run-dependency>
172
                    </run-dependency>
173
                </dependency>
173
                </dependency>
174
                <dependency>
174
                <dependency>
(-)a/web.clientproject/src/org/netbeans/modules/web/clientproject/ClientSideProjectConvertor.java (-61 / +11 lines)
Lines 42-51 Link Here
42
package org.netbeans.modules.web.clientproject;
42
package org.netbeans.modules.web.clientproject;
43
43
44
import java.io.BufferedReader;
44
import java.io.BufferedReader;
45
import java.io.Closeable;
45
import java.io.IOException;
46
import java.io.IOException;
46
import java.io.InputStreamReader;
47
import java.io.InputStreamReader;
47
import java.io.Reader;
48
import java.io.Reader;
48
import java.nio.charset.Charset;
49
import java.nio.charset.StandardCharsets;
49
import java.nio.charset.StandardCharsets;
50
import java.util.concurrent.Callable;
50
import java.util.concurrent.Callable;
51
import java.util.logging.Level;
51
import java.util.logging.Level;
Lines 56-74 Link Here
56
import org.netbeans.api.annotations.common.CheckForNull;
56
import org.netbeans.api.annotations.common.CheckForNull;
57
import org.netbeans.api.annotations.common.NonNull;
57
import org.netbeans.api.annotations.common.NonNull;
58
import org.netbeans.api.java.classpath.ClassPath;
58
import org.netbeans.api.java.classpath.ClassPath;
59
import org.netbeans.api.project.FileOwnerQuery;
60
import org.netbeans.api.project.Project;
59
import org.netbeans.api.project.Project;
61
import org.netbeans.modules.web.clientproject.api.util.StringUtilities;
60
import org.netbeans.modules.web.clientproject.api.util.StringUtilities;
62
import org.netbeans.modules.web.clientproject.createprojectapi.ClientSideProjectGenerator;
61
import org.netbeans.modules.web.clientproject.createprojectapi.ClientSideProjectGenerator;
63
import org.netbeans.modules.web.clientproject.createprojectapi.CreateProjectProperties;
62
import org.netbeans.modules.web.clientproject.createprojectapi.CreateProjectProperties;
64
import org.netbeans.spi.java.classpath.ClassPathProvider;
63
import org.netbeans.spi.java.classpath.ClassPathProvider;
65
import org.netbeans.spi.project.ui.ProjectConvertor;
64
import org.netbeans.spi.project.ui.ProjectConvertor;
66
import org.netbeans.spi.queries.FileEncodingQueryImplementation;
65
import org.netbeans.spi.project.ui.support.ProjectConvertors;
67
import org.openide.filesystems.FileObject;
66
import org.openide.filesystems.FileObject;
68
import org.openide.util.ImageUtilities;
67
import org.openide.util.ImageUtilities;
69
import org.openide.util.Lookup;
68
import org.openide.util.Lookup;
70
import org.openide.util.lookup.Lookups;
71
import org.openide.util.lookup.ProxyLookup;
72
69
73
/**
70
/**
74
 * The {@link ProjectConvertor} implements for web client project.
71
 * The {@link ProjectConvertor} implements for web client project.
Lines 104-115 Link Here
104
            // should not happen often
101
            // should not happen often
105
            displayName = projectDirectory.getNameExt();
102
            displayName = projectDirectory.getNameExt();
106
        }
103
        }
107
        final TransientLookup transientLkp = new TransientLookup(
104
        final Lookup transientLkp = ProjectConvertors.createProjectConvertorLookup(
108
            new ConvertorClassPathProvider(),
105
            new ConvertorClassPathProvider(),
109
            new ConvertorFileEncodingQuery());
106
            ProjectConvertors.createFileEncodingQuery());
110
        return new Result(
107
        return new Result(
111
                transientLkp,
108
                transientLkp,
112
                new Factory(projectDirectory, displayName, transientLkp),
109
                new Factory(projectDirectory, displayName, (Closeable)transientLkp),
113
                displayName,
110
                displayName,
114
                ImageUtilities.image2Icon(ImageUtilities.loadImage(ClientSideProject.HTML5_PROJECT_ICON)));
111
                ImageUtilities.image2Icon(ImageUtilities.loadImage(ClientSideProject.HTML5_PROJECT_ICON)));
115
    }
112
    }
Lines 144-153 Link Here
144
141
145
        private final FileObject projectDirectory;
142
        private final FileObject projectDirectory;
146
        private final String displayName;
143
        private final String displayName;
147
        private final TransientLookup transientLkp;
144
        private final Closeable transientLkp;
148
145
149
146
150
        Factory(FileObject projectDirectory, String displayName, TransientLookup transientLkp) {
147
        Factory(FileObject projectDirectory, String displayName, Closeable transientLkp) {
151
            assert projectDirectory != null;
148
            assert projectDirectory != null;
152
            assert displayName != null : projectDirectory;
149
            assert displayName != null : projectDirectory;
153
            assert transientLkp != null: projectDirectory;
150
            assert transientLkp != null: projectDirectory;
Lines 158-166 Link Here
158
155
159
        @Override
156
        @Override
160
        public Project call() throws Exception {
157
        public Project call() throws Exception {
161
            transientLkp.hide(
158
            transientLkp.close();
162
                ConvertorClassPathProvider.class,
163
                ConvertorFileEncodingQuery.class);
164
            return ClientSideProjectGenerator.createProject(new CreateProjectProperties(projectDirectory, displayName)
159
            return ClientSideProjectGenerator.createProject(new CreateProjectProperties(projectDirectory, displayName)
165
                    .setSourceFolder("") // NOI18N
160
                    .setSourceFolder("") // NOI18N
166
                    .setSiteRootFolder(detectSiteRoot())
161
                    .setSiteRootFolder(detectSiteRoot())
Lines 180-243 Link Here
180
175
181
    }
176
    }
182
177
183
    private static final class TransientLookup extends ProxyLookup {
184
185
        private final Lookup base;
186
187
        public TransientLookup(Object... services) {
188
            this(Lookups.fixed(services));
189
        }
190
191
        private TransientLookup(Lookup base) {
192
            super(base);
193
            this.base = base;
194
        }
195
196
        void hide(Class<?>... clzs) {
197
            setLookups(Lookups.exclude(base, clzs));
198
        }
199
    }
200
201
    private static class ConvertorClassPathProvider implements ClassPathProvider {
178
    private static class ConvertorClassPathProvider implements ClassPathProvider {
202
203
        @Override
179
        @Override
204
        @CheckForNull
180
        @CheckForNull
205
        public ClassPath findClassPath(
181
        public ClassPath findClassPath(
206
                @NonNull final FileObject file,
182
                @NonNull final FileObject file,
207
                @NonNull final String type) {
183
                @NonNull final String type) {
208
            if (ClassPathProviderImpl.SOURCE_CP.equals(type)) {
184
            if (ClassPathProviderImpl.SOURCE_CP.equals(type)) {
209
                final ClientSideProject csp = findClientSideProject(file);
185
                final Project p = ProjectConvertors.getNonConvertorOwner(file);
210
                if (csp != null) {
186
                if (p != null) {
211
                    return csp.getLookup().lookup(ClassPathProvider.class).findClassPath(file, type);
187
                    return p.getLookup().lookup(ClassPathProvider.class).findClassPath(file, type);
212
                }
188
                }
213
            }
189
            }
214
            return null;
190
            return null;
215
        }
191
        }
216
    }
192
    }
217
218
    private static class ConvertorFileEncodingQuery extends FileEncodingQueryImplementation {
219
220
        @Override
221
        @CheckForNull
222
        public Charset getEncoding(FileObject file) {
223
            final ClientSideProject csp = findClientSideProject(file);
224
            return csp != null ?
225
                csp.getLookup().lookup(FileEncodingQueryImplementation.class).getEncoding(file) :
226
                null;
227
        }
228
    }
229
230
    @CheckForNull
231
    @SuppressWarnings("NestedAssignment")
232
    private static ClientSideProject findClientSideProject(@NonNull final FileObject file) {
233
        for (FileObject parent = file.getParent(); parent != null; parent = parent.getParent()) {
234
            ClientSideProject csPrj;
235
            final Project prj = FileOwnerQuery.getOwner(parent);
236
            if (prj != null && (csPrj = prj.getLookup().lookup(ClientSideProject.class)) != null) {
237
                return csPrj;
238
            }
239
        }
240
        return null;
241
    }
242
243
}
193
}

Return to bug 253338