| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.netbeans.modules.j2ee.earproject; |
| |
| import java.beans.PropertyChangeEvent; |
| import java.beans.PropertyChangeListener; |
| import java.io.File; |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| import javax.swing.Icon; |
| import org.netbeans.api.java.classpath.ClassPath; |
| import org.netbeans.api.java.classpath.GlobalPathRegistry; |
| import org.netbeans.api.project.Project; |
| import org.netbeans.api.project.ProjectManager; |
| import org.netbeans.api.project.ant.AntArtifact; |
| import org.netbeans.api.project.ant.AntBuildExtender; |
| import org.netbeans.modules.j2ee.api.ejbjar.Car; |
| import org.netbeans.modules.j2ee.api.ejbjar.Ear; |
| import org.netbeans.modules.j2ee.api.ejbjar.EjbJar; |
| import org.netbeans.modules.j2ee.common.SharabilityUtility; |
| import org.netbeans.modules.java.api.common.classpath.ClassPathSupport; |
| import org.netbeans.modules.javaee.project.api.ant.ui.J2EEProjectProperties; |
| import org.netbeans.modules.j2ee.common.ui.BrokenServerSupport; |
| import org.netbeans.modules.j2ee.deployment.devmodules.api.Deployment; |
| import org.netbeans.modules.j2ee.deployment.devmodules.api.InstanceRemovedException; |
| import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eePlatform; |
| import org.netbeans.api.j2ee.core.Profile; |
| import org.netbeans.api.java.platform.JavaPlatform; |
| import org.netbeans.api.project.FileOwnerQuery; |
| import org.netbeans.api.project.ProjectUtils; |
| import org.netbeans.api.project.ui.ProjectProblems; |
| import org.netbeans.modules.j2ee.common.dd.DDHelper; |
| import org.netbeans.modules.j2ee.dd.api.application.Application; |
| import org.netbeans.modules.j2ee.dd.api.application.DDProvider; |
| import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule; |
| import org.netbeans.modules.javaee.project.spi.JavaEEProjectSettingsImplementation; |
| import org.netbeans.modules.javaee.project.api.ant.DeployOnSaveUtils; |
| import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule.Type; |
| import org.netbeans.modules.j2ee.deployment.devmodules.api.ModuleListener; |
| import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeModuleProvider; |
| import org.netbeans.modules.j2ee.earproject.classpath.ClassPathProviderImpl; |
| import org.netbeans.modules.j2ee.earproject.classpath.ClassPathSupportCallbackImpl; |
| import org.netbeans.modules.j2ee.earproject.ui.IconBaseProvider; |
| import org.netbeans.modules.j2ee.earproject.ui.J2eeArchiveLogicalViewProvider; |
| import org.netbeans.modules.j2ee.earproject.ui.customizer.CustomizerProviderImpl; |
| import org.netbeans.modules.j2ee.earproject.ui.customizer.EarProjectProperties; |
| import org.netbeans.modules.j2ee.earproject.util.EarProjectUtil; |
| import org.netbeans.modules.j2ee.spi.ejbjar.EarImplementation; |
| import org.netbeans.modules.j2ee.spi.ejbjar.EarImplementation2; |
| import org.netbeans.modules.j2ee.spi.ejbjar.EjbJarFactory; |
| import org.netbeans.modules.java.api.common.Roots; |
| import org.netbeans.modules.java.api.common.ant.UpdateHelper; |
| import org.netbeans.modules.java.api.common.project.ProjectProperties; |
| import org.netbeans.modules.java.api.common.queries.QuerySupport; |
| import org.netbeans.modules.javaee.project.api.ClientSideDevelopmentSupport; |
| import org.netbeans.modules.javaee.project.api.JavaEEProjectSettingConstants; |
| import org.netbeans.modules.javaee.project.api.JavaEEProjectSettings; |
| import org.netbeans.modules.javaee.project.api.problems.PlatformUpdatedCallBackImpl; |
| import org.netbeans.modules.javaee.project.spi.ear.EarDDGeneratorImplementation; |
| import org.netbeans.modules.web.api.webmodule.WebModule; |
| import org.netbeans.spi.java.project.support.LookupMergerSupport; |
| import org.netbeans.spi.java.project.support.ui.BrokenReferencesSupport; |
| import org.netbeans.spi.project.AuxiliaryConfiguration; |
| import org.netbeans.spi.project.SubprojectProvider; |
| import org.netbeans.spi.project.ant.AntArtifactProvider; |
| import org.netbeans.spi.project.ant.AntBuildExtenderFactory; |
| import org.netbeans.spi.project.ant.AntBuildExtenderImplementation; |
| import org.netbeans.spi.project.support.LookupProviderSupport; |
| import org.netbeans.spi.project.support.ant.AntBasedProjectRegistration; |
| import org.netbeans.spi.project.support.ant.AntProjectEvent; |
| import org.netbeans.spi.project.support.ant.AntProjectHelper; |
| import org.netbeans.spi.project.support.ant.AntProjectListener; |
| import org.netbeans.spi.project.support.ant.EditableProperties; |
| import org.netbeans.spi.project.support.ant.GeneratedFilesHelper; |
| import org.netbeans.spi.project.support.ant.ProjectXmlSavedHook; |
| import org.netbeans.spi.project.support.ant.PropertyEvaluator; |
| import org.netbeans.spi.project.support.ant.PropertyUtils; |
| import org.netbeans.spi.project.support.ant.ReferenceHelper; |
| import org.netbeans.spi.project.ui.PrivilegedTemplates; |
| import org.netbeans.spi.project.ui.ProjectOpenedHook; |
| import org.netbeans.spi.project.ui.RecommendedTemplates; |
| import org.netbeans.spi.project.ui.support.UILookupMergerSupport; |
| import org.openide.filesystems.FileObject; |
| import org.openide.filesystems.FileStateInvalidException; |
| import org.openide.filesystems.FileSystem.AtomicAction; |
| import org.openide.filesystems.FileUtil; |
| import org.openide.util.Exceptions; |
| import org.openide.util.ImageUtilities; |
| import org.openide.util.Lookup; |
| import org.openide.util.Mutex; |
| import org.openide.util.NbBundle; |
| import org.openide.util.lookup.Lookups; |
| import org.openide.util.lookup.ProxyLookup; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.NodeList; |
| |
| /** |
| * Represents an Enterprise Application project. |
| * |
| * This is the project api centric view of the enterprise application. |
| * |
| * @author vince kraemer |
| */ |
| @AntBasedProjectRegistration( |
| iconResource="org/netbeans/modules/j2ee/earproject/ui/resources/projectIcon.gif", |
| type=EarProjectType.TYPE, |
| sharedNamespace=EarProjectType.PROJECT_CONFIGURATION_NAMESPACE, |
| privateNamespace=EarProjectType.PRIVATE_CONFIGURATION_NAMESPACE |
| ) |
| public final class EarProject implements Project, AntProjectListener { |
| |
| private static Logger LOGGER = Logger.getLogger(EarProject.class.getName()); |
| |
| private final Icon EAR_PROJECT_ICON = ImageUtilities.loadImageIcon("org/netbeans/modules/j2ee/earproject/ui/resources/projectIcon.gif", false); // NOI18N |
| public static final String ARTIFACT_TYPE_EAR = "ear"; |
| |
| private final AntProjectHelper helper; |
| private final PropertyEvaluator eval; |
| private final ReferenceHelper refHelper; |
| private final GeneratedFilesHelper genFilesHelper; |
| private final Lookup lookup; |
| private final ProjectEar appModule; |
| private final Ear ear; |
| private final UpdateHelper updateHelper; |
| private final UpdateProjectImpl updateProject; |
| private final ClassPathProviderImpl cpProvider; |
| private PropertyChangeListener j2eePlatformListener; |
| private EarProjectLookup earLookup; |
| private final ClientSideDevelopmentSupport easelSupport; |
| |
| private AntBuildExtender buildExtender; |
| public ClassPathSupport cs; |
| |
| public EarProject(final AntProjectHelper helper) throws IOException { |
| this.helper = helper; |
| eval = createEvaluator(); |
| AuxiliaryConfiguration aux = helper.createAuxiliaryConfiguration(); |
| refHelper = new ReferenceHelper(helper, aux, helper.getStandardPropertyEvaluator()); |
| buildExtender = AntBuildExtenderFactory.createAntExtender(new EarExtenderImplementation()); |
| genFilesHelper = new GeneratedFilesHelper(helper,buildExtender); |
| appModule = new ProjectEar(this); |
| ear = EjbJarFactory.createEar(new EarImpl2(appModule)); |
| updateProject = new UpdateProjectImpl(this, this.helper, aux); |
| updateHelper = new UpdateHelper(updateProject, helper); |
| cpProvider = new ClassPathProviderImpl(helper, evaluator()); |
| easelSupport = ClientSideDevelopmentSupport.createInstance(this, EarProjectType.TYPE, EarProjectUtil.USG_LOGGER_NAME); |
| helper.addAntProjectListener(new AntProjectListener() { |
| |
| @Override |
| public void configurationXmlChanged(AntProjectEvent ev) { |
| } |
| |
| @Override |
| public void propertiesChanged(AntProjectEvent ev) { |
| updateEaselWebProject(); |
| } |
| }); |
| lookup = createLookup(aux, cpProvider); |
| cs = new ClassPathSupport( eval, refHelper, |
| updateHelper.getAntProjectHelper(), updateHelper, new ClassPathSupportCallbackImpl(helper)); |
| updateEaselWebProject(); |
| } |
| |
| private void updateEaselWebProject() { |
| Project p = null; |
| List<ClassPathSupport.Item> vcpis = EarProjectProperties.getJarContentAdditional(this); |
| for (ClassPathSupport.Item item : vcpis) { |
| if (item.getType() != ClassPathSupport.Item.TYPE_ARTIFACT || item.getArtifact() == null) { |
| continue; |
| } |
| Project vcpiProject = item.getArtifact().getProject(); |
| J2eeModuleProvider jmp = vcpiProject.getLookup().lookup(J2eeModuleProvider.class); |
| if (null != jmp && jmp.getJ2eeModule().getType() == Type.WAR) { |
| p = vcpiProject; |
| break; |
| } |
| } |
| easelSupport.setWebProject(p); |
| } |
| |
| public ClassPathSupport getClassPathSupport() { |
| return cs; |
| } |
| |
| public UpdateHelper getUpdateHelper() { |
| return updateHelper; |
| } |
| |
| public FileObject getProjectDirectory() { |
| return helper.getProjectDirectory(); |
| } |
| |
| public ClientSideDevelopmentSupport getEaselSupport() { |
| return easelSupport; |
| } |
| |
| public ReferenceHelper getReferenceHelper() { |
| return refHelper; |
| } |
| |
| @Override |
| public String toString() { |
| return "EarProject[" + getProjectDirectory() + "]"; // NOI18N |
| } |
| |
| private PropertyEvaluator createEvaluator() { |
| // XXX might need to use a custom evaluator to handle active platform substitutions... TBD |
| return helper.getStandardPropertyEvaluator(); |
| } |
| |
| public PropertyEvaluator evaluator() { |
| return eval; |
| } |
| |
| public Lookup getLookup() { |
| return lookup; |
| } |
| |
| public AntProjectHelper getAntProjectHelper() { |
| return helper; |
| } |
| |
| private Lookup createLookup(AuxiliaryConfiguration aux, ClassPathProviderImpl cpProvider) { |
| SubprojectProvider spp = refHelper.createSubprojectProvider(); |
| final J2eeArchiveLogicalViewProvider lvp = new J2eeArchiveLogicalViewProvider(this, updateHelper, evaluator(), refHelper, appModule); |
| Lookup base = Lookups.fixed(new Object[] { |
| QuerySupport.createProjectInformation(helper, this, EAR_PROJECT_ICON), |
| aux, |
| spp, |
| helper.createAuxiliaryProperties(), |
| new ProjectEarProvider(), |
| appModule, //implements J2eeModuleProvider |
| // FIXME this is just fallback for code searching for the old SPI in lookup |
| // remove in next release |
| new EarImpl(ear, appModule), |
| new EarActionProvider(this, updateHelper), |
| lvp, |
| new MyIconBaseProvider(), |
| new CustomizerProviderImpl(this, helper, refHelper), |
| LookupMergerSupport.createClassPathProviderMerger(cpProvider), |
| new ProjectXmlSavedHookImpl(), |
| UILookupMergerSupport.createProjectOpenHookMerger(new ProjectOpenedHookImpl()), |
| QuerySupport.createSources(this, helper, evaluator(), |
| Roots.propertyBased(new String[]{EarProjectProperties.META_INF}, new String[]{NbBundle.getMessage(EarProject.class, "LBL_Node_ConfigBase")}, false, null, null)), |
| new RecommendedTemplatesImpl(), |
| helper.createSharabilityQuery(evaluator(), |
| new String[] {"${"+EarProjectProperties.SOURCE_ROOT+"}"}, // NOI18N |
| new String[] { |
| "${"+ProjectProperties.BUILD_DIR+"}", // NOI18N |
| "${"+EarProjectProperties.DIST_DIR+"}"} // NOI18N |
| ), |
| this, |
| new EarProjectOperations(this), |
| new AntArtifactProviderImpl(), |
| UILookupMergerSupport.createPrivilegedTemplatesMerger(), |
| UILookupMergerSupport.createRecommendedTemplatesMerger(), |
| LookupProviderSupport.createSourcesMerger(), |
| buildExtender, |
| new SourceForBinaryQueryImpl(this), |
| new JavaEEProjectSettingsImpl(this), |
| new EarDDGeneratorImpl(this), |
| easelSupport, |
| BrokenReferencesSupport.createReferenceProblemsProvider(helper, refHelper, eval, lvp.getBreakableProperties(), lvp.getPlatformProperties()), |
| BrokenReferencesSupport.createPlatformVersionProblemProvider(helper, eval, PlatformUpdatedCallBackImpl.create(EarProjectType.PROJECT_CONFIGURATION_NAMESPACE, updateHelper, false, new String[]{"name", "minimum-ant-version","use-manifest"}), JavaPlatform.getDefault().getSpecification().getName(), ProjectProperties.PLATFORM_ACTIVE, ProjectProperties.JAVAC_SOURCE, ProjectProperties.JAVAC_TARGET), |
| UILookupMergerSupport.createProjectProblemsProviderMerger(), |
| }); |
| earLookup = new EarProjectLookup(this, base, new WebBrowserProvider(this)); |
| evaluator().addPropertyChangeListener(earLookup); |
| return LookupProviderSupport.createCompositeLookup(earLookup, "Projects/org-netbeans-modules-j2ee-earproject/Lookup"); //NOI18N |
| } |
| |
| private static class EarProjectLookup extends ProxyLookup implements PropertyChangeListener{ |
| private Lookup base; |
| private EarProject project; |
| private WebBrowserProvider webProvider; |
| |
| public EarProjectLookup(EarProject project, Lookup base, WebBrowserProvider webProvider) { |
| super(base); |
| this.project = project; |
| this.base = base; |
| this.webProvider = webProvider; |
| updateLookup(); |
| } |
| |
| private void updateLookup() { |
| if ("true".equals(project.evaluator().getProperty(EarProjectProperties.DISPLAY_BROWSER)) && |
| project.evaluator().getProperty(EarProjectProperties.APPLICATION_CLIENT) == null) { |
| setLookups(base, Lookups.singleton(webProvider)); |
| } else { |
| setLookups(base); |
| } |
| } |
| |
| public void propertyChange(PropertyChangeEvent evt) { |
| if (evt.getPropertyName().equals(EarProjectProperties.DISPLAY_BROWSER) || |
| evt.getPropertyName().equals(EarProjectProperties.APPLICATION_CLIENT)) { |
| updateLookup(); |
| } |
| } |
| } |
| |
| public void configurationXmlChanged(AntProjectEvent ev) { |
| } |
| |
| public void propertiesChanged(AntProjectEvent ev) { |
| // currently ignored |
| //TODO: should not be ignored! |
| } |
| |
| public String getBuildXmlName() { |
| String storedName = helper.getStandardPropertyEvaluator().getProperty(EarProjectProperties.BUILD_FILE); |
| return storedName == null ? GeneratedFilesHelper.BUILD_XML_PATH : storedName; |
| } |
| |
| // Package private methods ------------------------------------------------- |
| |
| public ProjectEar getAppModule() { |
| return appModule; |
| } |
| |
| public Ear getEar() { |
| return ear; |
| } |
| |
| /** Store configured project name. */ |
| public void setName(final String name) { |
| ProjectManager.mutex().writeAccess(new Mutex.Action<Void>() { |
| public Void run() { |
| Element data = helper.getPrimaryConfigurationData(true); |
| // XXX replace by XMLUtil when that has findElement, findText, etc. |
| NodeList nl = data.getElementsByTagNameNS(EarProjectType.PROJECT_CONFIGURATION_NAMESPACE, "name"); // NOI18N |
| Element nameEl; |
| if (nl.getLength() == 1) { |
| nameEl = (Element) nl.item(0); |
| NodeList deadKids = nameEl.getChildNodes(); |
| while (deadKids.getLength() > 0) { |
| nameEl.removeChild(deadKids.item(0)); |
| } |
| } else { |
| nameEl = data.getOwnerDocument().createElementNS(EarProjectType.PROJECT_CONFIGURATION_NAMESPACE, "name"); // NOI18N |
| data.insertBefore(nameEl, /* OK if null */data.getChildNodes().item(0)); |
| } |
| nameEl.appendChild(data.getOwnerDocument().createTextNode(name)); |
| helper.putPrimaryConfigurationData(data, true); |
| return null; |
| } |
| }); |
| } |
| |
| public void registerJ2eePlatformListener(final J2eePlatform platform) { |
| // listen to classpath changes |
| j2eePlatformListener = new PropertyChangeListener() { |
| public void propertyChange(PropertyChangeEvent evt) { |
| if (evt.getPropertyName().equals(J2eePlatform.PROP_CLASSPATH)) { |
| ProjectManager.mutex().writeAccess(new Mutex.Action<Void>() { |
| public Void run() { |
| EditableProperties ep = helper.getProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH); |
| EditableProperties projectProps = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH); |
| Map<String, String> roots = J2EEProjectProperties.extractPlatformLibrariesRoot(platform); |
| String classpath = J2EEProjectProperties.toClasspathString(platform.getClasspathEntries(), roots); |
| ep.setProperty(J2EEProjectProperties.J2EE_PLATFORM_CLASSPATH, classpath); |
| helper.putProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH, ep); |
| try { |
| ProjectManager.getDefault().saveProject(EarProject.this); |
| } catch (IOException e) { |
| Exceptions.printStackTrace(e); |
| } |
| return null; |
| } |
| }); |
| } |
| } |
| }; |
| platform.addPropertyChangeListener(j2eePlatformListener); |
| } |
| |
| public void unregisterJ2eePlatformListener(J2eePlatform platform) { |
| if (j2eePlatformListener != null) { |
| platform.removePropertyChangeListener(j2eePlatformListener); |
| } |
| } |
| |
| // Private innerclasses ---------------------------------------------------- |
| private final class ProjectXmlSavedHookImpl extends ProjectXmlSavedHook { |
| |
| ProjectXmlSavedHookImpl() {} |
| |
| protected void projectXmlSaved() throws IOException { |
| genFilesHelper.refreshBuildScript( |
| GeneratedFilesHelper.BUILD_IMPL_XML_PATH, |
| EarProject.class.getResource("resources/build-impl.xsl"), |
| false); |
| genFilesHelper.refreshBuildScript( |
| getBuildXmlName(), |
| EarProject.class.getResource("resources/build.xsl"), |
| false); |
| } |
| |
| } |
| |
| /** Package-private for unit tests only. */ |
| final class ProjectOpenedHookImpl extends ProjectOpenedHook { |
| |
| ProjectOpenedHookImpl() {} |
| |
| protected void projectOpened() { |
| helper.getStandardPropertyEvaluator().addPropertyChangeListener(EarProject.this.appModule); |
| |
| J2eeArchiveLogicalViewProvider logicalViewProvider = (J2eeArchiveLogicalViewProvider) EarProject.this.getLookup().lookup (J2eeArchiveLogicalViewProvider.class); |
| if (logicalViewProvider != null) { |
| logicalViewProvider.initialize(); |
| } |
| |
| try { |
| getAppModule().setModules(EarProjectProperties.getModuleMap(EarProject.this)); |
| // Check up on build scripts. |
| genFilesHelper.refreshBuildScript( |
| GeneratedFilesHelper.BUILD_IMPL_XML_PATH, |
| EarProject.class.getResource("resources/build-impl.xsl"), |
| true); |
| genFilesHelper.refreshBuildScript( |
| getBuildXmlName(), |
| EarProject.class.getResource("resources/build.xsl"), |
| true); |
| } catch (IOException e) { |
| LOGGER.log(Level.INFO, null, e); |
| } |
| |
| |
| // Register copy on save support |
| try { |
| getAppModule().copyOnSaveSupport.initialize(); |
| } |
| catch (FileStateInvalidException e) { |
| LOGGER.log(Level.INFO, null, e); |
| } |
| |
| // register project's classpaths to GlobalPathRegistry |
| GlobalPathRegistry.getDefault().register(ClassPath.BOOT, cpProvider.getProjectClassPaths(ClassPath.BOOT)); |
| |
| try { |
| getProjectDirectory().getFileSystem().runAtomicAction(new AtomicAction() { |
| public void run() throws IOException { |
| ProjectManager.mutex().writeAccess(new Runnable() { |
| public void run() { |
| updateProject(); |
| } |
| }); |
| } |
| }); |
| |
| } catch (IOException e ) { |
| Exceptions.printStackTrace(e); |
| } |
| |
| String compileOnSave = EarProject.this.getUpdateHelper(). |
| getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH).getProperty(EarProjectProperties.J2EE_COMPILE_ON_SAVE); |
| if (Boolean.parseBoolean(compileOnSave)) { |
| Deployment.getDefault().enableCompileOnSaveSupport(appModule); |
| } |
| |
| if (logicalViewProvider != null && logicalViewProvider.hasBrokenLinks()) { |
| ProjectProblems.showAlert(EarProject.this); |
| } |
| |
| String servInstID = EarProject.this.getUpdateHelper(). |
| getProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH). |
| getProperty(EarProjectProperties.J2EE_SERVER_INSTANCE); |
| J2eePlatform platform = Deployment.getDefault().getJ2eePlatform(servInstID); |
| String serverType = null; |
| if (platform != null) { |
| // updates j2ee.platform.cp & wscompile.cp & reg. j2ee platform listener |
| EarProjectProperties.setServerInstance(EarProject.this, EarProject.this.updateHelper, servInstID); |
| } else { |
| // if there is some server instance of the type which was used |
| // previously do not ask and use it |
| serverType = EarProject.this.getUpdateHelper(). |
| getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH). |
| getProperty(EarProjectProperties.J2EE_SERVER_TYPE); |
| if (serverType != null) { |
| String instanceID = J2EEProjectProperties.getMatchingInstance(serverType, Type.EAR, EarProject.this.getJ2eeProfile()); |
| if (instanceID != null) { |
| EarProjectProperties.setServerInstance(EarProject.this, EarProject.this.updateHelper, instanceID); |
| platform = Deployment.getDefault().getJ2eePlatform(instanceID); |
| } |
| } |
| if (platform == null) { |
| BrokenServerSupport.showAlert(); |
| } |
| } |
| |
| // initialize the server configuration |
| // it MUST BE called AFTER classpaths are registered to GlobalPathRegistry |
| // and after server resolve!! |
| // DDProvider (used here) needs classpath set correctly when resolving Java Extents for annotations |
| J2eeModuleProvider pwm = EarProject.this.getLookup().lookup(J2eeModuleProvider.class); |
| pwm.getConfigSupport().ensureConfigurationReady(); |
| |
| |
| // the only purpose of below code is to force deployment descriptor |
| // creation if necesary (that is if JEE 1.4 and dd file is missing) |
| if (pwm.getConfigSupport().isDescriptorRequired() || Profile.J2EE_14.equals(getJ2eeProfile())) { |
| appModule.getMetadataModel(); |
| } |
| |
| // UI Logging |
| EarProjectUtil.logUI(NbBundle.getBundle(EarProject.class), "UI_EAR_PROJECT_OPENED", // NOI18N |
| new Object[] {(serverType != null ? serverType : Deployment.getDefault().getServerID(servInstID)), servInstID}); |
| |
| // Usage Logging |
| String serverName = ""; // NOI18N |
| try { |
| if (servInstID != null) { |
| serverName = Deployment.getDefault().getServerInstance(servInstID).getServerDisplayName(); |
| } |
| } |
| catch (InstanceRemovedException ier) { |
| // ignore |
| } |
| EarProjectUtil.logUsage(EarProject.class, "USG_PROJECT_OPEN_EAR", new Object[] { serverName }); // NOI18N |
| } |
| |
| private void updateProject() { |
| // Make it easier to run headless builds on the same machine at least. |
| EditableProperties ep = helper.getProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH); |
| ep.setProperty("netbeans.user", System.getProperty("netbeans.user")); |
| |
| // #134642 - use Ant task from copylibs library |
| SharabilityUtility.makeSureProjectHasCopyLibsLibrary(helper, refHelper); |
| |
| //update lib references in project properties |
| EditableProperties props = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH); |
| J2EEProjectProperties.removeObsoleteLibraryLocations(ep); |
| J2EEProjectProperties.removeObsoleteLibraryLocations(props); |
| |
| if (props.getProperty(EarProjectProperties.J2EE_DEPLOY_ON_SAVE) == null) { |
| String server = evaluator().getProperty(EarProjectProperties.J2EE_SERVER_INSTANCE); |
| props.setProperty(EarProjectProperties.J2EE_DEPLOY_ON_SAVE, |
| server == null ? "false" : DeployOnSaveUtils.isDeployOnSaveSupported(server)); |
| } |
| |
| if (props.getProperty(EarProjectProperties.J2EE_COMPILE_ON_SAVE) == null) { |
| props.setProperty(EarProjectProperties.J2EE_COMPILE_ON_SAVE, |
| props.getProperty(EarProjectProperties.J2EE_DEPLOY_ON_SAVE)); |
| } |
| |
| helper.putProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH, props); |
| |
| helper.putProperties(AntProjectHelper.PRIVATE_PROPERTIES_PATH, ep); |
| try { |
| ProjectManager.getDefault().saveProject(EarProject.this); |
| } catch (IOException e) { |
| Exceptions.printStackTrace(e); |
| } |
| } |
| |
| protected void projectClosed() { |
| helper.getStandardPropertyEvaluator().removePropertyChangeListener(EarProject.this.appModule); |
| |
| // listen to j2ee platform classpath changes |
| EditableProperties privateProperties = updateHelper.getProperties( AntProjectHelper.PRIVATE_PROPERTIES_PATH ); |
| String servInstID = privateProperties.getProperty(EarProjectProperties.J2EE_SERVER_INSTANCE); |
| J2eePlatform platform = Deployment.getDefault().getJ2eePlatform(servInstID); |
| if (platform != null) { |
| unregisterJ2eePlatformListener(platform); |
| } |
| |
| // Probably unnecessary, but just in case: |
| try { |
| ProjectManager.getDefault().saveProject(EarProject.this); |
| } catch (IOException e) { |
| Exceptions.printStackTrace(e); |
| } |
| |
| // Unregister copy on save support |
| try { |
| getAppModule().copyOnSaveSupport.cleanup(); |
| } |
| catch (FileStateInvalidException e) { |
| LOGGER.log(Level.INFO, null, e); |
| } |
| |
| Deployment.getDefault().disableCompileOnSaveSupport(appModule); |
| |
| // unregister project's classpaths to GlobalPathRegistry |
| GlobalPathRegistry.getDefault().unregister(ClassPath.BOOT, cpProvider.getProjectClassPaths(ClassPath.BOOT)); |
| |
| easelSupport.close(); |
| } |
| |
| } |
| |
| private static final class RecommendedTemplatesImpl implements RecommendedTemplates, PrivilegedTemplates { |
| |
| // List of primarily supported templates |
| |
| private static final String[] TYPES = new String[] { |
| "XML", // NOI18N |
| "ear-types", // NOI18N |
| "wsdl", // NOI18N |
| "simple-files", // NOI18N |
| "ant-script", // NOI18N |
| "ant-task", // NOI18N |
| }; |
| |
| private static final String[] PRIVILEGED_NAMES = new String[] { |
| "Templates/J2EE/ApplicationXml", // NOI18N |
| "deployment-descriptor", // NOI18N |
| }; |
| public String[] getRecommendedTypes() { |
| return TYPES; |
| } |
| public String[] getPrivilegedTemplates() { |
| return PRIVILEGED_NAMES; |
| } |
| } |
| |
| static class MyIconBaseProvider implements IconBaseProvider { |
| public String getIconBase() { |
| return "org/netbeans/modules/j2ee/earproject/ui/resources/"; // NOI18N |
| } |
| } |
| |
| /** May return <code>null</code>. */ |
| public FileObject getOrCreateMetaInfDir() { |
| String metaInfProp = helper.getStandardPropertyEvaluator(). |
| getProperty(EarProjectProperties.META_INF); |
| if (metaInfProp == null) { |
| // IZ 91941 |
| // does project.properties exist? if yes, something is probably wrong... |
| File projectProperties = helper.resolveFile(AntProjectHelper.PROJECT_PROPERTIES_PATH); |
| if (projectProperties.exists()) { |
| // file exists, log warning |
| if (LOGGER.isLoggable(Level.WARNING)) { |
| LOGGER.log(Level.WARNING, |
| "Cannot resolve {0} property for {1}", // NOI18N |
| new Object[] {EarProjectProperties.META_INF, this}); |
| } |
| } |
| metaInfProp = "src/conf"; // NOI18N |
| } |
| FileObject metaInfFO = null; |
| try { |
| File prjDirF = FileUtil.toFile(getProjectDirectory()); |
| File metaInfF = PropertyUtils.resolveFile(prjDirF, metaInfProp); |
| metaInfFO = FileUtil.createFolder(metaInfF); |
| } catch (IOException ex) { |
| LOGGER.log(Level.INFO, null, ex); |
| } |
| return metaInfFO; |
| } |
| |
| FileObject getFileObject(String propname) { |
| String prop = helper.getStandardPropertyEvaluator().getProperty(propname); |
| if (prop != null) { |
| return helper.resolveFileObject(prop); |
| } else { |
| return null; |
| } |
| } |
| |
| File getFile(String propname) { |
| String prop = helper.getStandardPropertyEvaluator().getProperty(propname); |
| if (prop != null) { |
| return helper.resolveFile(prop); |
| } else { |
| return null; |
| } |
| } |
| |
| public String getServerID() { |
| return helper.getStandardPropertyEvaluator().getProperty(EarProjectProperties.J2EE_SERVER_TYPE); |
| } |
| |
| public String getServerInstanceID() { |
| return helper.getStandardPropertyEvaluator().getProperty(EarProjectProperties.J2EE_SERVER_INSTANCE); |
| } |
| |
| @Deprecated |
| public String getJ2eePlatformVersion() { |
| return helper.getStandardPropertyEvaluator().getProperty(EarProjectProperties.J2EE_PLATFORM); |
| } |
| |
| public Profile getJ2eeProfile() { |
| return Profile.fromPropertiesString(helper.getStandardPropertyEvaluator().getProperty(EarProjectProperties.J2EE_PLATFORM)); |
| } |
| |
| public GeneratedFilesHelper getGeneratedFilesHelper() { |
| return genFilesHelper; |
| } |
| |
| private final class AntArtifactProviderImpl implements AntArtifactProvider{ |
| public AntArtifact[] getBuildArtifacts() { |
| return new AntArtifact[] { |
| helper.createSimpleAntArtifact(ARTIFACT_TYPE_EAR, "dist.jar", evaluator(), "dist", "clean"), // NOI18N |
| }; |
| } |
| |
| } |
| |
| // FIXME this is just fallback for code searching for the old SPI in lookup |
| // remove in next release |
| @SuppressWarnings("deprecation") |
| private static class EarImpl implements EarImplementation { |
| |
| private final Ear apiEar; |
| |
| private final ProjectEar projectEar; |
| |
| public EarImpl(Ear apiEar, ProjectEar projectEar) { |
| this.apiEar = apiEar; |
| this.projectEar = projectEar; |
| } |
| |
| public void addCarModule(Car module) { |
| apiEar.addCarModule(module); |
| } |
| |
| public void addEjbJarModule(EjbJar module) { |
| apiEar.addEjbJarModule(module); |
| } |
| |
| public void addWebModule(WebModule module) { |
| apiEar.addWebModule(module); |
| } |
| |
| public FileObject getDeploymentDescriptor() { |
| return apiEar.getDeploymentDescriptor(); |
| } |
| |
| public String getJ2eePlatformVersion() { |
| return apiEar.getJ2eePlatformVersion(); |
| } |
| |
| public FileObject getMetaInf() { |
| return projectEar.getMetaInf(); |
| } |
| } |
| |
| private static class EarImpl2 implements EarImplementation2 { |
| |
| private final ProjectEar projectEar; |
| |
| public EarImpl2(ProjectEar projectEar) { |
| this.projectEar = projectEar; |
| } |
| |
| public void addCarModule(Car module) { |
| projectEar.addCarModule(module); |
| } |
| |
| public void addEjbJarModule(EjbJar module) { |
| projectEar.addEjbJarModule(module); |
| } |
| |
| public void addWebModule(WebModule module) { |
| projectEar.addWebModule(module); |
| } |
| |
| public FileObject getDeploymentDescriptor() { |
| return projectEar.getDeploymentDescriptor(); |
| } |
| |
| public Profile getJ2eeProfile() { |
| return projectEar.getJ2eeProfile(); |
| } |
| |
| public FileObject getMetaInf() { |
| return projectEar.getMetaInf(); |
| } |
| |
| } |
| |
| private class EarExtenderImplementation implements AntBuildExtenderImplementation { |
| //add targets here as required by the external plugins.. |
| public List<String> getExtensibleTargets() { |
| String[] targets = new String[] { |
| "pre-dist", //NOI18N |
| }; |
| return Arrays.asList(targets); |
| } |
| |
| public Project getOwningProject() { |
| return EarProject.this; |
| } |
| |
| } |
| |
| private class JavaEEProjectSettingsImpl implements JavaEEProjectSettingsImplementation { |
| |
| private final EarProject project; |
| |
| public JavaEEProjectSettingsImpl(EarProject project) { |
| this.project = project; |
| evaluator().addPropertyChangeListener(new PropertyChangeListener() { |
| @Override |
| public void propertyChange(PropertyChangeEvent evt) { |
| if (EarProjectProperties.SELECTED_BROWSER.equals(evt.getPropertyName())) { |
| easelSupport.resetBrowserSupport(); |
| } |
| } |
| }); |
| } |
| |
| @Override |
| public void setProfile(Profile profile) { |
| setInSharedProperties(JavaEEProjectSettingConstants.J2EE_PLATFORM, profile.toPropertiesString()); |
| } |
| |
| @Override |
| public Profile getProfile() { |
| return project.getJ2eeProfile(); |
| } |
| |
| @Override |
| public void setBrowserID(String browserID) { |
| setInPrivateProperties(JavaEEProjectSettingConstants.SELECTED_BROWSER, browserID); |
| } |
| |
| @Override |
| public String getBrowserID() { |
| return evaluator().getProperty(JavaEEProjectSettingConstants.SELECTED_BROWSER); |
| } |
| |
| @Override |
| public void setServerInstanceID(String serverInstanceID) { |
| setInPrivateProperties(JavaEEProjectSettingConstants.J2EE_SERVER_INSTANCE, serverInstanceID); |
| } |
| |
| @Override |
| public String getServerInstanceID() { |
| return evaluator().getProperty(JavaEEProjectSettingConstants.J2EE_SERVER_INSTANCE); |
| } |
| |
| private void setInSharedProperties(String key, String value) { |
| setInProperties(key, value, AntProjectHelper.PROJECT_PROPERTIES_PATH); |
| } |
| |
| private void setInPrivateProperties(String key, String value) { |
| setInProperties(key, value, AntProjectHelper.PRIVATE_PROPERTIES_PATH); |
| } |
| |
| private void setInProperties(String key, String value, String propertiesPath) { |
| try { |
| UpdateHelper helper = project.getUpdateHelper(); |
| EditableProperties projectProperties = helper.getProperties(propertiesPath); |
| projectProperties.setProperty(key, value); |
| helper.putProperties(propertiesPath, projectProperties); |
| ProjectManager.getDefault().saveProject(project); |
| } catch (IOException ex) { |
| LOGGER.log(Level.WARNING, "Project properties couldn't be saved.", ex); |
| } |
| } |
| } |
| |
| private static final class EarDDGeneratorImpl implements EarDDGeneratorImplementation { |
| |
| final Project project; |
| |
| public EarDDGeneratorImpl(Project project) { |
| this.project = project; |
| } |
| |
| @Override |
| public FileObject setupDD(boolean force) { |
| //#118047 avoid using the EarProject instance directly to allow for alternate implementations. |
| EarImplementation earImpl = project.getLookup().lookup(EarImplementation.class); |
| if (earImpl == null) { |
| return null; |
| } |
| |
| FileObject metaInf = earImpl.getMetaInf(); |
| FileObject dd = metaInf.getFileObject(ProjectEar.FILE_DD); |
| if (dd != null) { |
| return dd; // already created |
| } |
| |
| Profile profile = JavaEEProjectSettings.getProfile(project); |
| boolean create = force || DDHelper.isApplicationXMLCompulsory(project); |
| |
| try { |
| dd = DDHelper.createApplicationXml(profile, metaInf, create); |
| if (dd != null) { |
| Application app = DDProvider.getDefault().getDDRoot(dd); |
| app.setDisplayName(ProjectUtils.getInformation(project).getDisplayName()); |
| //#118047 avoiding the use of EarProject not possible here. |
| // API for retrieval of getJarContentAdditional() not present. |
| EarProject defInst = project.getLookup().lookup(EarProject.class); |
| if (defInst != null) { |
| for (ClassPathSupport.Item vcpi : EarProjectProperties.getJarContentAdditional(defInst)) { |
| EarProjectProperties.addItemToAppDD(defInst, app, vcpi); |
| } |
| } |
| app.write(dd); |
| } |
| return dd; |
| } catch (IOException ex) { |
| return null; |
| } |
| } |
| } |
| } |