~ubuntu-branches/ubuntu/quantal/netbeans/quantal

« back to all changes in this revision

Viewing changes to j2ee/clientproject/src/org/netbeans/modules/j2ee/clientproject/AppClientProject.java

  • Committer: Bazaar Package Importer
  • Author(s): Marek Slama
  • Date: 2008-01-29 14:11:22 UTC
  • Revision ID: james.westby@ubuntu.com-20080129141122-fnzjbo11ntghxfu7
Tags: upstream-6.0.1
ImportĀ upstreamĀ versionĀ 6.0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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-2007 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.modules.j2ee.clientproject;
 
43
 
 
44
import java.beans.PropertyChangeEvent;
 
45
import java.beans.PropertyChangeListener;
 
46
import java.beans.PropertyChangeSupport;
 
47
import java.io.File;
 
48
import java.io.IOException;
 
49
import java.lang.ref.WeakReference;
 
50
import java.net.URI;
 
51
import java.util.Arrays;
 
52
import java.util.LinkedList;
 
53
import java.util.List;
 
54
import java.util.logging.Level;
 
55
import java.util.logging.Logger;
 
56
import javax.swing.Icon;
 
57
import javax.swing.ImageIcon;
 
58
import javax.swing.JButton;
 
59
import org.netbeans.api.java.classpath.ClassPath;
 
60
import org.netbeans.api.java.classpath.GlobalPathRegistry;
 
61
import org.netbeans.api.java.project.JavaProjectConstants;
 
62
import org.netbeans.api.project.FileOwnerQuery;
 
63
import org.netbeans.api.project.Project;
 
64
import org.netbeans.api.project.ProjectInformation;
 
65
import org.netbeans.api.project.ProjectManager;
 
66
import org.netbeans.api.project.ant.AntArtifact;
 
67
import org.netbeans.api.project.ant.AntBuildExtender;
 
68
import org.netbeans.modules.j2ee.api.ejbjar.Car;
 
69
import org.netbeans.modules.j2ee.clientproject.classpath.AppClientProjectClassPathExtender;
 
70
import org.netbeans.modules.j2ee.clientproject.classpath.ClassPathProviderImpl;
 
71
import org.netbeans.modules.j2ee.clientproject.classpath.ClassPathSupport;
 
72
import org.netbeans.modules.j2ee.clientproject.queries.AppClientProjectEncodingQueryImpl;
 
73
import org.netbeans.modules.j2ee.clientproject.queries.CompiledSourceForBinaryQuery;
 
74
import org.netbeans.modules.j2ee.clientproject.queries.JavadocForBinaryQueryImpl;
 
75
import org.netbeans.modules.j2ee.clientproject.queries.SourceLevelQueryImpl;
 
76
import org.netbeans.modules.j2ee.clientproject.queries.UnitTestForSourceQueryImpl;
 
77
import org.netbeans.modules.j2ee.clientproject.ui.AppClientLogicalViewProvider;
 
78
import org.netbeans.modules.j2ee.clientproject.ui.customizer.AppClientProjectProperties;
 
79
import org.netbeans.modules.j2ee.clientproject.ui.customizer.CustomizerProviderImpl;
 
80
import org.netbeans.modules.j2ee.clientproject.wsclient.AppClientProjectJAXWSClientSupport;
 
81
import org.netbeans.modules.j2ee.clientproject.wsclient.AppClientProjectJAXWSVersionProvider;
 
82
import org.netbeans.modules.j2ee.clientproject.wsclient.AppClientProjectWebServicesClientSupport;
 
83
import org.netbeans.modules.j2ee.clientproject.wsclient.AppClientProjectWebServicesSupportProvider;
 
84
import org.netbeans.modules.j2ee.common.ui.BrokenServerSupport;
 
85
import org.netbeans.modules.j2ee.deployment.devmodules.api.Deployment;
 
86
import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eePlatform;
 
87
import org.netbeans.modules.j2ee.spi.ejbjar.CarFactory;
 
88
import org.netbeans.modules.websvc.api.client.WebServicesClientSupport;
 
89
import org.netbeans.modules.websvc.api.jaxws.client.JAXWSClientSupport;
 
90
import org.netbeans.modules.websvc.api.jaxws.project.WSUtils;
 
91
import org.netbeans.modules.websvc.spi.client.WebServicesClientSupportFactory;
 
92
import org.netbeans.modules.websvc.spi.jaxws.client.JAXWSClientSupportFactory;
 
93
import org.netbeans.spi.java.project.support.ui.BrokenReferencesSupport;
 
94
import org.netbeans.spi.project.AuxiliaryConfiguration;
 
95
import org.netbeans.spi.project.SubprojectProvider;
 
96
import org.netbeans.spi.project.ant.AntArtifactProvider;
 
97
import org.netbeans.spi.project.ant.AntBuildExtenderFactory;
 
98
import org.netbeans.spi.project.ant.AntBuildExtenderImplementation;
 
99
import org.netbeans.spi.project.support.LookupProviderSupport;
 
100
import org.netbeans.spi.project.support.ant.AntProjectEvent;
 
101
import org.netbeans.spi.project.support.ant.AntProjectHelper;
 
102
import org.netbeans.spi.project.support.ant.AntProjectListener;
 
103
import org.netbeans.spi.project.support.ant.EditableProperties;
 
104
import org.netbeans.spi.project.support.ant.GeneratedFilesHelper;
 
105
import org.netbeans.spi.project.support.ant.ProjectXmlSavedHook;
 
106
import org.netbeans.spi.project.support.ant.PropertyEvaluator;
 
107
import org.netbeans.spi.project.support.ant.PropertyUtils;
 
108
import org.netbeans.spi.project.support.ant.ReferenceHelper;
 
109
import org.netbeans.spi.project.support.ant.SourcesHelper;
 
110
import org.netbeans.spi.project.ui.PrivilegedTemplates;
 
111
import org.netbeans.spi.project.ui.ProjectOpenedHook;
 
112
import org.netbeans.spi.project.ui.RecommendedTemplates;
 
113
import org.netbeans.spi.project.ui.support.UILookupMergerSupport;
 
114
import org.openide.DialogDisplayer;
 
115
import org.openide.NotifyDescriptor;
 
116
import org.openide.filesystems.FileAttributeEvent;
 
117
import org.openide.filesystems.FileChangeListener;
 
118
import org.openide.filesystems.FileEvent;
 
119
import org.openide.filesystems.FileObject;
 
120
import org.openide.filesystems.FileRenameEvent;
 
121
import org.openide.filesystems.FileSystem.AtomicAction;
 
122
import org.openide.filesystems.FileUtil;
 
123
import org.openide.loaders.DataObject;
 
124
import org.openide.loaders.DataObjectNotFoundException;
 
125
import org.openide.util.Exceptions;
 
126
import org.openide.util.Lookup;
 
127
import org.openide.util.Mutex;
 
128
import org.openide.util.NbBundle;
 
129
import org.openide.util.RequestProcessor;
 
130
import org.openide.util.Utilities;
 
131
import org.openide.util.lookup.Lookups;
 
132
import org.w3c.dom.Element;
 
133
import org.w3c.dom.Node;
 
134
import org.w3c.dom.NodeList;
 
135
import org.w3c.dom.Text;
 
136
 
 
137
/**
 
138
 * Represents one plain Application Client project.
 
139
 * @author Jesse Glick, et al.
 
140
 */
 
141
public final class AppClientProject implements Project, AntProjectListener, FileChangeListener {
 
142
    
 
143
    private static final Icon CAR_PROJECT_ICON = new ImageIcon(Utilities.loadImage("org/netbeans/modules/j2ee/clientproject/ui/resources/appclient.gif")); // NOI18N
 
144
    
 
145
    private final AuxiliaryConfiguration aux;
 
146
    private final AntProjectHelper helper;
 
147
    private final PropertyEvaluator eval;
 
148
    private final ReferenceHelper refHelper;
 
149
    private final GeneratedFilesHelper genFilesHelper;
 
150
    private final Lookup lookup;
 
151
    private final UpdateHelper updateHelper;
 
152
    private MainClassUpdater mainClassUpdater;
 
153
    private SourceRoots sourceRoots;
 
154
    private SourceRoots testRoots;
 
155
    
 
156
    // WS client support
 
157
    private AppClientProjectWebServicesClientSupport carProjectWebServicesClientSupport;
 
158
    private AppClientProjectJAXWSClientSupport jaxWsClientSupport;
 
159
    private WebServicesClientSupport apiWebServicesClientSupport;
 
160
    private JAXWSClientSupport apiJAXWSClientSupport;
 
161
    
 
162
    private PropertyChangeListener j2eePlatformListener;
 
163
    private final AppClientProvider appClient;
 
164
    private final Car apiJar;
 
165
    private JarContainerImpl enterpriseResourceSupport;
 
166
    private FileObject libFolder;
 
167
    private final AppClientProjectClassPathExtender classpathExtender;
 
168
    private final ClassPathProviderImpl cpProvider;
 
169
    
 
170
    // use AntBuildExtender to enable Ant Extensibility
 
171
    private AntBuildExtender buildExtender;
 
172
    
 
173
    AppClientProject(AntProjectHelper helper) throws IOException {
 
174
        this.helper = helper;
 
175
        eval = createEvaluator();
 
176
        aux = helper.createAuxiliaryConfiguration();
 
177
        refHelper = new ReferenceHelper(helper, aux, eval);
 
178
        buildExtender = AntBuildExtenderFactory.createAntExtender(new AppClientExtenderImplementation());
 
179
        genFilesHelper = new GeneratedFilesHelper(helper, buildExtender);
 
180
        this.updateHelper = new UpdateHelper(this, this.helper, this.aux, this.genFilesHelper,
 
181
                UpdateHelper.createDefaultNotifier());
 
182
        carProjectWebServicesClientSupport = new AppClientProjectWebServicesClientSupport(this, helper, refHelper);
 
183
        jaxWsClientSupport = new AppClientProjectJAXWSClientSupport(this, helper);
 
184
        apiWebServicesClientSupport = WebServicesClientSupportFactory.createWebServicesClientSupport(carProjectWebServicesClientSupport);
 
185
        apiJAXWSClientSupport = JAXWSClientSupportFactory.createJAXWSClientSupport(jaxWsClientSupport);
 
186
        cpProvider = new ClassPathProviderImpl(this.helper, evaluator(), getSourceRoots(),getTestSourceRoots());
 
187
        appClient = new AppClientProvider(this, helper, cpProvider);
 
188
        apiJar = CarFactory.createCar(appClient);
 
189
        enterpriseResourceSupport = new JarContainerImpl(this, refHelper, helper);
 
190
        classpathExtender = new AppClientProjectClassPathExtender(this, updateHelper, evaluator(), refHelper);
 
191
        lookup = createLookup(aux, cpProvider);
 
192
        helper.addAntProjectListener(this);
 
193
    }
 
194
    
 
195
    /**
 
196
     * Returns the project directory
 
197
     * @return the directory the project is located in
 
198
     */
 
199
    public FileObject getProjectDirectory() {
 
200
        return helper.getProjectDirectory();
 
201
    }
 
202
    
 
203
    @Override
 
204
    public String toString() {
 
205
        return "CarProject[" + getProjectDirectory() + "]"; // NOI18N
 
206
    }
 
207
    
 
208
    private PropertyEvaluator createEvaluator() {
 
209
        // XXX might need to use a custom evaluator to handle active platform substitutions... TBD
 
210
        // It is currently safe to not use the UpdateHelper for PropertyEvaluator; UH.getProperties() delegates to APH
 
211
        return helper.getStandardPropertyEvaluator();
 
212
    }
 
213
    
 
214
    public PropertyEvaluator evaluator() {
 
215
        return eval;
 
216
    }
 
217
    
 
218
    public ReferenceHelper getReferenceHelper() {
 
219
        return this.refHelper;
 
220
    }
 
221
    
 
222
    public UpdateHelper getUpdateHelper() {
 
223
        return this.updateHelper;
 
224
    }
 
225
    
 
226
    public Lookup getLookup() {
 
227
        return lookup;
 
228
    }
 
229
    
 
230
    public AntProjectHelper getAntProjectHelper() {
 
231
        return helper;
 
232
    }
 
233
    
 
234
    private Lookup createLookup(AuxiliaryConfiguration aux, ClassPathProviderImpl cpProvider) {
 
235
        SubprojectProvider spp = refHelper.createSubprojectProvider();
 
236
 
 
237
        final SourcesHelper sourcesHelper = new SourcesHelper(helper, evaluator());
 
238
        String configFilesLabel = NbBundle.getMessage(AppClientLogicalViewProvider.class, "LBL_Node_ConfFiles"); //NOI18N
 
239
        
 
240
        //sourcesHelper.addPrincipalSourceRoot("${"+AppClientProjectProperties.SOURCE_ROOT+"}", ejbModuleLabel, /*XXX*/null, null);
 
241
        sourcesHelper.addPrincipalSourceRoot("${"+AppClientProjectProperties.META_INF+"}", configFilesLabel, /*XXX*/null, null); // NOI18N
 
242
        
 
243
        ProjectManager.mutex().postWriteRequest(new Runnable() {
 
244
            public void run() {
 
245
                sourcesHelper.registerExternalRoots(FileOwnerQuery.EXTERNAL_ALGORITHM_TRANSIENT);
 
246
            }
 
247
        });
 
248
        Lookup base = Lookups.fixed(new Object[] {
 
249
            new Info(),
 
250
            aux,
 
251
            helper.createCacheDirectoryProvider(),
 
252
            spp,
 
253
            new AppClientActionProvider( this, helper, this.updateHelper ),
 
254
            new AppClientLogicalViewProvider(this, this.updateHelper, evaluator(), refHelper),
 
255
            // new J2SECustomizerProvider(this, this.updateHelper, evaluator(), refHelper),
 
256
            new CustomizerProviderImpl(this, this.updateHelper, evaluator(), refHelper, this.genFilesHelper),
 
257
            new ClassPathProviderMerger(cpProvider),
 
258
            new CompiledSourceForBinaryQuery(this.helper, evaluator(),getSourceRoots(),getTestSourceRoots()), //Does not use APH to get/put properties/cfgdata
 
259
            new JavadocForBinaryQueryImpl(this.helper, evaluator()), //Does not use APH to get/put properties/cfgdata
 
260
            new AntArtifactProviderImpl(),
 
261
            new ProjectXmlSavedHookImpl(),
 
262
            UILookupMergerSupport.createProjectOpenHookMerger(new ProjectOpenedHookImpl()),
 
263
            new UnitTestForSourceQueryImpl(getSourceRoots(),getTestSourceRoots()),
 
264
            new SourceLevelQueryImpl(evaluator()),
 
265
            new AppClientSources(this.helper, evaluator(), getSourceRoots(), getTestSourceRoots()),
 
266
            new AppClientSharabilityQuery(this.helper, evaluator(), getSourceRoots(), getTestSourceRoots()), //Does not use APH to get/put properties/cfgdata
 
267
            new AppClientFileBuiltQuery(this.helper, evaluator(),getSourceRoots(),getTestSourceRoots()), //Does not use APH to get/put properties/cfgdata
 
268
            new AppClientProjectEncodingQueryImpl(evaluator()), 
 
269
            new RecommendedTemplatesImpl(this.updateHelper),
 
270
            classpathExtender,
 
271
            buildExtender,
 
272
            AppClientProject.this, // never cast an externally obtained Project to AppClientProject - use lookup instead
 
273
            new AppClientProjectOperations(this),
 
274
            new AppClientProjectWebServicesSupportProvider(),
 
275
            
 
276
            new ProjectAppClientProvider(this),
 
277
            appClient,
 
278
            new AppClientPersistenceProvider(this, evaluator(), cpProvider),
 
279
            new AppClientProjectJAXWSVersionProvider(helper),
 
280
            enterpriseResourceSupport,
 
281
            UILookupMergerSupport.createPrivilegedTemplatesMerger(),
 
282
            UILookupMergerSupport.createRecommendedTemplatesMerger(),
 
283
            LookupProviderSupport.createSourcesMerger()
 
284
        });
 
285
        return LookupProviderSupport.createCompositeLookup(base, "Projects/org-netbeans-modules-j2ee-clientproject/Lookup"); //NOI18N
 
286
    }
 
287
    
 
288
    public ClassPathProviderImpl getClassPathProvider () {
 
289
        return this.cpProvider;
 
290
    }
 
291
    
 
292
    public void configurationXmlChanged(AntProjectEvent ev) {
 
293
        if (ev.getPath().equals(AntProjectHelper.PROJECT_XML_PATH)) {
 
294
            // Could be various kinds of changes, but name & displayName might have changed.
 
295
            Info info = (Info)getLookup().lookup(ProjectInformation.class);
 
296
            info.firePropertyChange(ProjectInformation.PROP_NAME);
 
297
            info.firePropertyChange(ProjectInformation.PROP_DISPLAY_NAME);
 
298
        }
 
299
    }
 
300
    
 
301
    public void propertiesChanged(AntProjectEvent ev) {
 
302
        // currently ignored (probably better to listen to evaluator() if you need to)
 
303
    }
 
304
    
 
305
    // Package private methods -------------------------------------------------
 
306
    
 
307
    /**
 
308
     * Returns the source roots of this project
 
309
     * @return project's source roots
 
310
     */
 
311
    public synchronized SourceRoots getSourceRoots() {
 
312
        if (this.sourceRoots == null) { //Local caching, no project metadata access
 
313
            this.sourceRoots = new SourceRoots(this.updateHelper, evaluator(), getReferenceHelper(), "source-roots", false, "src.{0}{1}.dir"); //NOI18N
 
314
        }
 
315
        return this.sourceRoots;
 
316
    }
 
317
    
 
318
    public synchronized SourceRoots getTestSourceRoots() {
 
319
        if (this.testRoots == null) { //Local caching, no project metadata access
 
320
            this.testRoots = new SourceRoots(this.updateHelper, evaluator(), getReferenceHelper(), "test-roots", true, "test.{0}{1}.dir"); //NOI18N
 
321
        }
 
322
        return this.testRoots;
 
323
    }
 
324
    
 
325
    File getTestClassesDirectory() {
 
326
        String testClassesDir = evaluator().getProperty(AppClientProjectProperties.BUILD_TEST_CLASSES_DIR);
 
327
        if (testClassesDir == null) {
 
328
            return null;
 
329
        }
 
330
        return helper.resolveFile(testClassesDir);
 
331
    }
 
332
    
 
333
    // Currently unused (but see #47230):
 
334
    /** Store configured project name. */
 
335
    public void setName(final String name) {
 
336
        ProjectManager.mutex().writeAccess(new Runnable() {
 
337
            public void run() {
 
338
                Element data = helper.getPrimaryConfigurationData(true);
 
339
                // XXX replace by XMLUtil when that has findElement, findText, etc.
 
340
                NodeList nl = data.getElementsByTagNameNS(AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE, "name"); // NOI18N
 
341
                Element nameEl;
 
342
                if (nl.getLength() == 1) {
 
343
                    nameEl = (Element) nl.item(0);
 
344
                    NodeList deadKids = nameEl.getChildNodes();
 
345
                    while (deadKids.getLength() > 0) {
 
346
                        nameEl.removeChild(deadKids.item(0));
 
347
                    }
 
348
                } else {
 
349
                    nameEl = data.getOwnerDocument().createElementNS(AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE, "name"); // NOI18N
 
350
                    data.insertBefore(nameEl, /* OK if null */data.getChildNodes().item(0));
 
351
                }
 
352
                nameEl.appendChild(data.getOwnerDocument().createTextNode(name));
 
353
                helper.putPrimaryConfigurationData(data, true);
 
354
            }
 
355
        });
 
356
    }
 
357
    
 
358
    /** Return configured project name. */
 
359
    public String getName() {
 
360
        return ProjectManager.mutex().readAccess(new Mutex.Action<String>() {
 
361
            public String run() {
 
362
                Element data = updateHelper.getPrimaryConfigurationData(true);
 
363
                // XXX replace by XMLUtil when that has findElement, findText, etc.
 
364
                NodeList nl = data.getElementsByTagNameNS(AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE, "name"); // NOI18N
 
365
                if (nl.getLength() == 1) {
 
366
                    nl = nl.item(0).getChildNodes();
 
367
                    if (nl.getLength() == 1 && nl.item(0).getNodeType() == Node.TEXT_NODE) {
 
368
                        return ((Text) nl.item(0)).getNodeValue();
 
369
                    }
 
370
                }
 
371
                return "CAR???"; // NOI18N
 
372
            }
 
373
        });
 
374
    }
 
375
 
 
376
    public void fileAttributeChanged (FileAttributeEvent fe) {
 
377
    }    
 
378
    
 
379
    public void fileChanged (FileEvent fe) {
 
380
    }
 
381
    
 
382
    public void fileDataCreated (FileEvent fe) {
 
383
        FileObject fo = fe.getFile ();
 
384
        checkLibraryFolder (fo);
 
385
    }
 
386
    
 
387
    public void fileDeleted (FileEvent fe) {
 
388
    }
 
389
    
 
390
    public void fileFolderCreated (FileEvent fe) {
 
391
    }
 
392
    
 
393
    public void fileRenamed (FileRenameEvent fe) {
 
394
        FileObject fo = fe.getFile ();
 
395
        checkLibraryFolder (fo);
 
396
    }
 
397
 
 
398
    private void checkLibraryFolder (FileObject fo) {
 
399
        if (!FileUtil.isArchiveFile(fo)) {
 
400
            return;
 
401
        }
 
402
        
 
403
        if (fo.getParent ().equals (libFolder)) {
 
404
            try {
 
405
                classpathExtender.addArchiveFile(fo);
 
406
            } catch (IOException e) {
 
407
                Exceptions.printStackTrace(e);
 
408
            }
 
409
        }
 
410
    }
 
411
    
 
412
    public void registerJ2eePlatformListener(final J2eePlatform platform) {
 
413
        // listen to classpath changes
 
414
        j2eePlatformListener = new PropertyChangeListener() {
 
415
            public void propertyChange(PropertyChangeEvent evt) {
 
416
                if (evt.getPropertyName().equals(J2eePlatform.PROP_CLASSPATH)) {
 
417
                    ProjectManager.mutex().writeAccess(new Runnable() {
 
418
                        public void run() {
 
419
                            EditableProperties ep = helper.getProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH);
 
420
                            String classpath = Utils.toClasspathString(platform.getClasspathEntries());
 
421
                            ep.setProperty(AppClientProjectProperties.J2EE_PLATFORM_CLASSPATH, classpath);
 
422
                            helper.putProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH, ep);
 
423
                            try {
 
424
                                ProjectManager.getDefault().saveProject(AppClientProject.this);
 
425
                            } catch (IOException e) {
 
426
                                Exceptions.printStackTrace(e);
 
427
                            }
 
428
                        }
 
429
                    });
 
430
                }
 
431
            }
 
432
        };
 
433
        platform.addPropertyChangeListener(j2eePlatformListener);
 
434
    }
 
435
    
 
436
    public void unregisterJ2eePlatformListener(J2eePlatform platform) {
 
437
        if (j2eePlatformListener != null) {
 
438
            platform.removePropertyChangeListener(j2eePlatformListener);
 
439
        }
 
440
    }
 
441
    
 
442
    public Car getAPICar() {
 
443
        return apiJar;
 
444
    }
 
445
    
 
446
    public AppClientProvider getCarModule() {
 
447
        return appClient;
 
448
    }
 
449
    
 
450
    
 
451
    private String getProperty(String path, String name) {
 
452
        return helper.getProperties(path).getProperty(name);
 
453
    }
 
454
    
 
455
    String getBuildXmlName() {
 
456
        String storedName = helper.getStandardPropertyEvaluator().getProperty(AppClientProjectProperties.BUILD_FILE);
 
457
        return storedName == null ? GeneratedFilesHelper.BUILD_XML_PATH : storedName;
 
458
    }
 
459
        
 
460
    /**
 
461
     * Refreshes the build-impl.xml script. If it was modified by the user, it 
 
462
     * displays a confirmation dialog.
 
463
     *
 
464
     * @param askUserIfFlags only display the dialog if the state of the build script
 
465
     * contains these flags (along with {@link GeneratedFilesHelper#FLAG_MODIFIED}, 
 
466
     * which is always checked)
 
467
     * @param askInCurrentThread if false, asks in another thread
 
468
     */
 
469
    private void refreshBuildImplXml(int askUserIfFlags, boolean askInCurrentThread) {
 
470
        askUserIfFlags |= GeneratedFilesHelper.FLAG_MODIFIED;
 
471
        int flags = genFilesHelper.getBuildScriptState(
 
472
            GeneratedFilesHelper.BUILD_IMPL_XML_PATH,
 
473
            AppClientProject.class.getResource("resources/build-impl.xsl")); // NOI18N
 
474
        if ((flags & askUserIfFlags) == askUserIfFlags) {
 
475
            Runnable run = new Runnable () {
 
476
                public void run () {
 
477
                    JButton updateOption = new JButton (NbBundle.getMessage(AppClientProject.class, "CTL_Regenerate"));
 
478
                    if (DialogDisplayer.getDefault().notify(
 
479
                        new NotifyDescriptor (NbBundle.getMessage(AppClientProject.class,"TXT_BuildImplRegenerate"),
 
480
                            NbBundle.getMessage(AppClientProject.class,"TXT_BuildImplRegenerateTitle"),
 
481
                            NotifyDescriptor.DEFAULT_OPTION,
 
482
                            NotifyDescriptor.WARNING_MESSAGE,
 
483
                            new Object[] {
 
484
                                updateOption,
 
485
                                NotifyDescriptor.CANCEL_OPTION
 
486
                            },
 
487
                            updateOption)) == updateOption) {
 
488
                        try {
 
489
                            genFilesHelper.generateBuildScriptFromStylesheet(
 
490
                                GeneratedFilesHelper.BUILD_IMPL_XML_PATH,
 
491
                                AppClientProject.class.getResource("resources/build-impl.xsl")); // NOI18N
 
492
                        } catch (IOException e) {
 
493
                            Exceptions.printStackTrace(e);
 
494
                        } catch (IllegalStateException e) {
 
495
                            Exceptions.printStackTrace(e);
 
496
                        }
 
497
                    }
 
498
                }
 
499
            };
 
500
            if (askInCurrentThread) {
 
501
                run.run();
 
502
            } else {
 
503
                RequestProcessor.getDefault().post(run);
 
504
            }
 
505
        } else {
 
506
            try {
 
507
                genFilesHelper.refreshBuildScript(
 
508
                    GeneratedFilesHelper.BUILD_IMPL_XML_PATH,
 
509
                    AppClientProject.class.getResource("resources/build-impl.xsl"), // NOI18N
 
510
                    false);
 
511
            } catch (IOException e) {
 
512
                Exceptions.printStackTrace(e);
 
513
            }
 
514
        }
 
515
    }
 
516
    
 
517
    // Private innerclasses ----------------------------------------------------
 
518
    //when #110886 gets implemented, this class is obsolete    
 
519
    private final class Info implements ProjectInformation {
 
520
        
 
521
        private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
 
522
        
 
523
        private WeakReference<String> cachedName = null;
 
524
        
 
525
        Info() {}
 
526
        
 
527
        void firePropertyChange(String prop) {
 
528
            pcs.firePropertyChange(prop, null, null);
 
529
            synchronized (pcs) {
 
530
                cachedName = null;
 
531
            }
 
532
        }
 
533
        
 
534
        public String getName() {
 
535
            return PropertyUtils.getUsablePropertyName(getDisplayName());
 
536
        }
 
537
        
 
538
        public String getDisplayName() {
 
539
            synchronized (pcs) {
 
540
                if (cachedName != null) {
 
541
                    String dn = cachedName.get();
 
542
                    if (dn != null) {
 
543
                        return dn;
 
544
                    }
 
545
                }
 
546
            }
 
547
            String dn = ProjectManager.mutex().readAccess(new Mutex.Action<String>() {
 
548
                public String run() {
 
549
                    Element data = updateHelper.getPrimaryConfigurationData(true);
 
550
                    // XXX replace by XMLUtil when that has findElement, findText, etc.
 
551
                    NodeList nl = data.getElementsByTagNameNS(AppClientProjectType.PROJECT_CONFIGURATION_NAMESPACE, "name"); // NOI18N
 
552
                    if (nl.getLength() == 1) {
 
553
                        nl = nl.item(0).getChildNodes();
 
554
                        if (nl.getLength() == 1 && nl.item(0).getNodeType() == Node.TEXT_NODE) {
 
555
                            return ((Text) nl.item(0)).getNodeValue();
 
556
                        }
 
557
                    }
 
558
                    return "???"; // NOI18N
 
559
                }
 
560
            });
 
561
            synchronized (pcs) {
 
562
                cachedName = new WeakReference<String>(dn);
 
563
            }
 
564
            return dn;
 
565
        }
 
566
        
 
567
        public Icon getIcon() {
 
568
            return CAR_PROJECT_ICON;
 
569
        }
 
570
        
 
571
        public Project getProject() {
 
572
            return AppClientProject.this;
 
573
        }
 
574
        
 
575
        public void addPropertyChangeListener(PropertyChangeListener listener) {
 
576
            pcs.addPropertyChangeListener(listener);
 
577
        }
 
578
        
 
579
        public void removePropertyChangeListener(PropertyChangeListener listener) {
 
580
            pcs.removePropertyChangeListener(listener);
 
581
        }
 
582
        
 
583
    }
 
584
    
 
585
    private final class ProjectXmlSavedHookImpl extends ProjectXmlSavedHook {
 
586
        
 
587
        ProjectXmlSavedHookImpl() {}
 
588
        
 
589
        protected void projectXmlSaved() throws IOException {
 
590
            refreshBuildImplXml(0, false);
 
591
            
 
592
            genFilesHelper.refreshBuildScript(
 
593
                getBuildXmlName(),
 
594
                AppClientProject.class.getResource("resources/build.xsl"), //NOI18N
 
595
                false);
 
596
        }
 
597
        
 
598
    }
 
599
    
 
600
    /** Package-private for unit tests only. */
 
601
    final class ProjectOpenedHookImpl extends ProjectOpenedHook {
 
602
        
 
603
        ProjectOpenedHookImpl() {}
 
604
        
 
605
        protected void projectOpened() {
 
606
            // Check up on build scripts.
 
607
            try {
 
608
                //Check libraries and add them to classpath automatically
 
609
                String libFolderName = helper.getStandardPropertyEvaluator ().getProperty (AppClientProjectProperties.LIBRARIES_DIR);
 
610
 
 
611
                //DDDataObject initialization to be ready to listen on changes (#49656)
 
612
                try {
 
613
                    FileObject ddFO = appClient.getDeploymentDescriptor();
 
614
                    if (ddFO != null) {
 
615
                        DataObject.find(ddFO);
 
616
                    }
 
617
                } catch (DataObjectNotFoundException ex) {}
 
618
                
 
619
                if (libFolderName != null && helper.resolveFile (libFolderName).isDirectory ()) {
 
620
                    libFolder = helper.resolveFileObject(libFolderName);
 
621
                        FileObject children [] = libFolder.getChildren ();
 
622
                        List<FileObject> libs = new LinkedList<FileObject>();
 
623
                        for (int i = 0; i < children.length; i++) {
 
624
                            if (FileUtil.isArchiveFile(children[i])) {
 
625
                                libs.add(children[i]);
 
626
                            }
 
627
                        }
 
628
                        FileObject[] libsArray = new FileObject[libs.size()];
 
629
                        libs.toArray(libsArray);
 
630
                        classpathExtender.addArchiveFiles(AppClientProjectProperties.JAVAC_CLASSPATH, libsArray, ClassPathSupport.ELEMENT_INCLUDED_LIBRARIES);
 
631
                        libFolder.addFileChangeListener (AppClientProject.this);
 
632
                }
 
633
                
 
634
                // Check up on build scripts.
 
635
                
 
636
                refreshBuildImplXml( GeneratedFilesHelper.FLAG_OLD_PROJECT_XML, true);
 
637
                
 
638
                genFilesHelper.refreshBuildScript(
 
639
                    getBuildXmlName(),
 
640
                    AppClientProject.class.getResource("resources/build.xsl"), //NOI18N
 
641
                    true);
 
642
                
 
643
                String servInstID = getProperty(AntProjectHelper.PRIVATE_PROPERTIES_PATH, AppClientProjectProperties.J2EE_SERVER_INSTANCE);
 
644
                J2eePlatform platform = Deployment.getDefault().getJ2eePlatform(servInstID);
 
645
                if (platform != null) {
 
646
                    // updates j2ee.platform.cp & wscompile.cp & reg. j2ee platform listener
 
647
                    AppClientProjectProperties.setServerInstance(AppClientProject.this, AppClientProject.this.helper, servInstID);
 
648
                } else {
 
649
                    // if there is some server instance of the type which was used
 
650
                    // previously do not ask and use it
 
651
                    String serverType = getProperty(AntProjectHelper.PROJECT_PROPERTIES_PATH, AppClientProjectProperties.J2EE_SERVER_TYPE);
 
652
                    if (serverType != null) {
 
653
                        String[] servInstIDs = Deployment.getDefault().getInstancesOfServer(serverType);
 
654
                        if (servInstIDs.length > 0) {
 
655
                            AppClientProjectProperties.setServerInstance(AppClientProject.this, AppClientProject.this.helper, servInstIDs[0]);
 
656
                            platform = Deployment.getDefault().getJ2eePlatform(servInstIDs[0]);
 
657
                        }
 
658
                    }
 
659
                    if (platform == null) {
 
660
                        BrokenServerSupport.showAlert();
 
661
                    }
 
662
                }
 
663
            } catch (IOException e) {
 
664
                Logger.getLogger("global").log(Level.INFO, null, e);
 
665
            }
 
666
 
 
667
            
 
668
            // register project's classpaths to GlobalPathRegistry
 
669
            GlobalPathRegistry.getDefault().register(ClassPath.BOOT, cpProvider.getProjectClassPaths(ClassPath.BOOT));
 
670
            GlobalPathRegistry.getDefault().register(ClassPath.SOURCE, cpProvider.getProjectClassPaths(ClassPath.SOURCE));
 
671
            GlobalPathRegistry.getDefault().register(ClassPath.COMPILE, cpProvider.getProjectClassPaths(ClassPath.COMPILE));
 
672
            
 
673
            // initialize the server configuration
 
674
            // it MUST BE called AFTER classpaths are registered to GlobalPathRegistry!
 
675
            // AppClient DDProvider (used here) needs classpath set correctly when resolving Java Extents for annotations
 
676
            appClient.getConfigSupport().ensureConfigurationReady();
 
677
            
 
678
            //register updater of main.class
 
679
            //the updater is active only on the opened projects
 
680
            mainClassUpdater = new MainClassUpdater(AppClientProject.this, eval, updateHelper,
 
681
                    cpProvider.getProjectClassPaths(ClassPath.SOURCE)[0], AppClientProjectProperties.MAIN_CLASS);
 
682
 
 
683
            try {
 
684
                getProjectDirectory().getFileSystem().runAtomicAction(new AtomicAction() {
 
685
                    public void run() throws IOException {
 
686
                        ProjectManager.mutex().writeAccess(new Runnable() {
 
687
                            public void run() {
 
688
                                updateProject();
 
689
                            }
 
690
                        });
 
691
                    }
 
692
                });
 
693
                
 
694
            } catch (IOException e) {
 
695
                Exceptions.printStackTrace(e);
 
696
            }
 
697
            
 
698
            AppClientLogicalViewProvider physicalViewProvider =  AppClientProject.this.getLookup().lookup(AppClientLogicalViewProvider.class);
 
699
            if (physicalViewProvider != null &&  physicalViewProvider.hasBrokenLinks()) {
 
700
                BrokenReferencesSupport.showAlert();
 
701
            }
 
702
        }
 
703
        
 
704
        private void updateProject() {
 
705
            // Make it easier to run headless builds on the same machine at least.
 
706
            EditableProperties ep = updateHelper.getProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH);
 
707
            File buildProperties = new File(System.getProperty("netbeans.user"), "build.properties"); // NOI18N
 
708
            ep.setProperty("user.properties.file", buildProperties.getAbsolutePath()); //NOI18N
 
709
 
 
710
            // set jaxws.endorsed.dir property (for endorsed mechanism to be used with wsimport, wsgen)
 
711
            WSUtils.setJaxWsEndorsedDirProperty(ep);
 
712
 
 
713
            updateHelper.putProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH, ep);
 
714
 
 
715
            // update a dual build directory project to use a single build directory
 
716
            ep = updateHelper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH);
 
717
            String earBuildDir = ep.getProperty(AppClientProjectProperties.BUILD_EAR_CLASSES_DIR);
 
718
            if (null != earBuildDir) {
 
719
                // there is an BUILD_EAR_CLASSES_DIR property... we may
 
720
                //  need to change its value
 
721
                String buildDir = ep.getProperty(AppClientProjectProperties.BUILD_CLASSES_DIR);
 
722
                if (null != buildDir) {
 
723
                    // there is a value that we may need to change the
 
724
                    // BUILD_EAR_CLASSES_DIR property value to match.
 
725
                    if (!buildDir.equals(earBuildDir)) {
 
726
                        // the values do not match... update the property and save it
 
727
                        ep.setProperty(AppClientProjectProperties.BUILD_EAR_CLASSES_DIR,
 
728
                                buildDir);
 
729
                        updateHelper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH,
 
730
                                ep);
 
731
                    }
 
732
                    // else {
 
733
                    //   the values match and we don't need to do anything
 
734
                    // }
 
735
                }
 
736
                // else {
 
737
                //   the project doesn't have a BUILD_CLASSES_DIR property
 
738
                //   ** This is not an expected state, but if the project 
 
739
                //      properties evolve, this property may go away...
 
740
                // }
 
741
            }
 
742
            // else {
 
743
            //   there isn't a BUILD_EAR_CLASSES_DIR in this project...
 
744
            //     so we should not create one, by setting it.
 
745
            // }
 
746
 
 
747
            try {
 
748
                ProjectManager.getDefault().saveProject(AppClientProject.this);
 
749
            } catch (IOException e) {
 
750
                Exceptions.printStackTrace(e);
 
751
            }
 
752
        }
 
753
        
 
754
        protected void projectClosed() {
 
755
            
 
756
            // unregister j2ee platform classpath change listener
 
757
            String servInstID = getProperty(AntProjectHelper.PRIVATE_PROPERTIES_PATH, AppClientProjectProperties.J2EE_SERVER_INSTANCE);
 
758
            J2eePlatform platform = Deployment.getDefault().getJ2eePlatform(servInstID);
 
759
            if (platform != null) {
 
760
                unregisterJ2eePlatformListener(platform);
 
761
            }
 
762
 
 
763
            // Probably unnecessary, but just in case:
 
764
            try {
 
765
                ProjectManager.getDefault().saveProject(AppClientProject.this);
 
766
            } catch (IOException e) {
 
767
                Exceptions.printStackTrace(e);
 
768
            }
 
769
            
 
770
            // unregister project's classpaths to GlobalPathRegistry
 
771
            GlobalPathRegistry.getDefault().unregister(ClassPath.BOOT, cpProvider.getProjectClassPaths(ClassPath.BOOT));
 
772
            GlobalPathRegistry.getDefault().unregister(ClassPath.SOURCE, cpProvider.getProjectClassPaths(ClassPath.SOURCE));
 
773
            GlobalPathRegistry.getDefault().unregister(ClassPath.COMPILE, cpProvider.getProjectClassPaths(ClassPath.COMPILE));
 
774
            if (mainClassUpdater != null) {
 
775
                mainClassUpdater.unregister();
 
776
                mainClassUpdater = null;
 
777
            }
 
778
        }
 
779
        
 
780
    }
 
781
    
 
782
    public WebServicesClientSupport getAPIWebServicesClientSupport() {
 
783
        return apiWebServicesClientSupport;
 
784
    }
 
785
 
 
786
    public JAXWSClientSupport getAPIJAXWSClientSupport() {
 
787
        return apiJAXWSClientSupport;
 
788
    }
 
789
    
 
790
    /**
 
791
     * Exports the main JAR as an official build product for use from other scripts.
 
792
     * The type of the artifact will be {@link AntArtifact#TYPE_JAR}.
 
793
     */
 
794
    private final class AntArtifactProviderImpl implements AntArtifactProvider {
 
795
        
 
796
        public AntArtifact[] getBuildArtifacts() {
 
797
            return new AntArtifact[] {
 
798
                helper.createSimpleAntArtifact(JavaProjectConstants.ARTIFACT_TYPE_JAR, "dist.jar", helper.getStandardPropertyEvaluator(), "dist", "clean"), // NOI18N
 
799
                //new CarAntArtifact(helper.createSimpleAntArtifact(AppClientProjectConstants.ARTIFACT_TYPE_CAR, "dist.jar", helper.getStandardPropertyEvaluator(), "dist", "clean")), // NOI18N
 
800
                new CarAntArtifact(helper.createSimpleAntArtifact(AppClientProjectConstants.ARTIFACT_TYPE_J2EE_MODULE_IN_EAR_ARCHIVE, "dist.ear.jar", helper.getStandardPropertyEvaluator(), "dist-ear", "clean-ear")) // NOI18N
 
801
        };
 
802
        }
 
803
        
 
804
    }
 
805
    
 
806
    private static final class RecommendedTemplatesImpl implements RecommendedTemplates, PrivilegedTemplates {
 
807
        
 
808
        RecommendedTemplatesImpl(UpdateHelper helper) {
 
809
            this.helper = helper;
 
810
        }
 
811
        
 
812
        transient private final UpdateHelper helper;
 
813
        transient private boolean isArchive = false;
 
814
        
 
815
        // List of primarily supported templates
 
816
        
 
817
        private static final String[] APPLICATION_TYPES = new String[] {
 
818
            "java-classes",         // NOI18N
 
819
            "java-main-class",      // NOI18N
 
820
            "j2ee-types",           // NOI18N                    
 
821
            "java-forms",           // NOI18N
 
822
            "gui-java-application", // NOI18N
 
823
            "java-beans",           // NOI18N
 
824
            "persistence",          // NOI18N
 
825
            "oasis-XML-catalogs",   // NOI18N
 
826
            "XML",                  // NOI18N
 
827
            "ant-script",           // NOI18N
 
828
            "ant-task",             // NOI18N
 
829
            "web-service-clients",  // NOI18N
 
830
            "wsdl",                 // NOI18N
 
831
            "sunresource-types",     // NOI18N
 
832
            // "web-types",         // NOI18N
 
833
            "junit",                // NOI18N
 
834
            // "MIDP",              // NOI18N
 
835
            "simple-files"          // NOI18N
 
836
        };
 
837
 
 
838
        private static final String[] PRIVILEGED_NAMES = new String[] {
 
839
            "Templates/Classes/Class.java", // NOI18N
 
840
            "Templates/Classes/Package", // NOI18N
 
841
            "Templates/Classes/Interface.java", // NOI18N
 
842
            "Templates/GUIForms/JPanel.java", // NOI18N
 
843
            "Templates/GUIForms/JFrame.java", // NOI18N
 
844
            "Templates/J2EE/CachingServiceLocator.java", //NOI18N
 
845
            "Templates/WebServices/WebServiceClient"   // NOI18N
 
846
        };
 
847
        
 
848
        private static final String[] APPLICATION_TYPES_ARCHIVE = new String[] {
 
849
            "deployment-descriptor",           // NOI18N                    
 
850
            "XML",                             // NOI18N
 
851
        };
 
852
        
 
853
        private static final String[] PRIVILEGED_NAMES_ARCHIVE = new String[] {
 
854
            "Templates/J2EE/applicationClientXml,"  // NOI18N
 
855
        };
 
856
 
 
857
        public String[] getRecommendedTypes() {
 
858
            String[] retVal = null;
 
859
            checkEnvironment();
 
860
            if (isArchive) {
 
861
                retVal = APPLICATION_TYPES_ARCHIVE.clone();
 
862
            } else {
 
863
                retVal = APPLICATION_TYPES.clone();
 
864
            }
 
865
            return retVal;
 
866
        }
 
867
        
 
868
        public String[] getPrivilegedTemplates() {
 
869
            String[] retVal = null;
 
870
            checkEnvironment();
 
871
            if (isArchive) {
 
872
                retVal = PRIVILEGED_NAMES_ARCHIVE.clone();
 
873
            } else {
 
874
                retVal = PRIVILEGED_NAMES.clone();
 
875
            }
 
876
            return retVal;
 
877
        }
 
878
 
 
879
        transient private boolean checked = false;
 
880
        
 
881
        private void checkEnvironment() {
 
882
            if (!checked) {
 
883
                final Object srcType = helper.getAntProjectHelper().
 
884
                        getStandardPropertyEvaluator().getProperty(AppClientProjectProperties.JAVA_SOURCE_BASED);
 
885
                if ("false".equals(srcType)) {
 
886
                    isArchive = true;
 
887
                }
 
888
                checked = true;
 
889
            }
 
890
        }
 
891
        
 
892
    }
 
893
 
 
894
    private final class CarAntArtifact extends AntArtifact {
 
895
    
 
896
        private final AntArtifact impl;
 
897
    
 
898
        CarAntArtifact(AntArtifact aa) {
 
899
            impl = aa;
 
900
        }
 
901
    
 
902
        @Override
 
903
        public String getID() {
 
904
            if (AppClientProjectConstants.ARTIFACT_TYPE_J2EE_MODULE_IN_EAR_ARCHIVE.equals(getType())) {
 
905
                return AppClientProjectConstants.CAR_ANT_ARTIFACT_ID;
 
906
            }
 
907
            return impl.getID();
 
908
        }
 
909
 
 
910
        public String getType() {
 
911
            return impl.getType();
 
912
        }
 
913
 
 
914
        public String getTargetName() {
 
915
            return impl.getTargetName();
 
916
        }
 
917
 
 
918
        public File getScriptLocation() {
 
919
            return impl.getScriptLocation();
 
920
        }
 
921
 
 
922
        public String getCleanTargetName() {
 
923
            return impl.getCleanTargetName();
 
924
        }
 
925
 
 
926
        @Override
 
927
        public URI[] getArtifactLocations() {
 
928
            return impl.getArtifactLocations();
 
929
        }
 
930
    
 
931
        @Override
 
932
        public Project getProject() {
 
933
            return impl.getProject();
 
934
        }
 
935
    
 
936
    }
 
937
    
 
938
    private class AppClientExtenderImplementation implements AntBuildExtenderImplementation {
 
939
        //add targets here as required by the external plugins..
 
940
        public List<String> getExtensibleTargets() {
 
941
            String[] targets = new String[] {
 
942
                "-do-init", "-init-check", "-post-clean", "jar", "-pre-pre-compile","-do-compile","-do-compile-single", "-pre-dist" //NOI18N
 
943
            };
 
944
            return Arrays.asList(targets);
 
945
        }
 
946
 
 
947
        public Project getOwningProject() {
 
948
            return AppClientProject.this;
 
949
        }
 
950
 
 
951
    }
 
952
    
 
953
}
 
954