blob: 1a2e7285b95897b861c9adffb41a8a3c72117f93 [file] [log] [blame]
/*
* 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;
}
}
}
}