() {
-
- @Override
- public Void call() throws Exception {
- ServerDebugInfo sdi = jmp.getServerDebugInfo();
-
- if (sdi != null) { //fix for bug 57854, this can be null
- String h = sdi.getHost();
- String transport = sdi.getTransport();
- String address;
-
- if (transport.equals(ServerDebugInfo.TRANSPORT_SHMEM)) {
- address = sdi.getShmemName();
- } else {
- address = Integer.toString(sdi.getPort());
- }
- MavenDebugger deb = project.getLookup().lookup(MavenDebugger.class);
- try {
- deb.attachDebugger(res.getInputOutput(), "Debug Deployed app", transport, h, address); // NOI18N
- } catch (Exception ex) {
- // See issue #235796 --> We were not able to attach debugger because
- // it's already attached, BUT we still want to deploy the application
- LOGGER.log(Level.FINE, "Exception occured while trying to attach debugger", ex); //NOI18N
- }
- }
- return null;
- }
- };
-
- }
-
- String clientUrl = Deployment.getDefault().deploy(jmp, mode, clientModuleUri,
- clientUrlPart, forceRedeploy, new DLogger(out), debuggerHook);
- if (clientUrl != null) {
- FileObject fo = project.getProjectDirectory();
- boolean show = showInBrowser;
- if (fo != null && show) {
- String browser = (String) fo.getAttribute(CustomizerRunWeb.PROP_SHOW_IN_BROWSER);
- show = browser != null ? Boolean.parseBoolean(browser) : true;
- }
- if (show) {
- URL url = new URL(clientUrl);
- URLDisplayerImplementation urlDisplayer = project.getLookup().lookup(URLDisplayerImplementation.class);
- if (urlDisplayer != null) {
- URL appRoot = url;
- if (clientUrlPart != null && clientUrlPart.length() > 0) {
- if (clientUrl.endsWith(clientUrlPart)) {
- appRoot = new URL(clientUrl.substring(0, clientUrl.length() - clientUrlPart.length()));
- }
- }
- urlDisplayer.showURL(appRoot, url, fo);
- } else {
- HtmlBrowser.URLDisplayer.getDefault().showURL(url);
- }
- }
- }
- } catch (Deployment.DeploymentException | MalformedURLException ex) {
- LOGGER.log(Level.FINE, "Exception occured wile deploying to Application Server.", ex); //NOI18N
- }
-
- // Reset the value of the one-time server
- if (oneTimeDeployment != null) {
- oneTimeDeployment.reset();
- MavenProjectSupport.changeServer(project, false);
- }
- }
-
@Override
public boolean checkRunConfig(RunConfig config) {
if (!isSupported()) { // #234767
@@ -316,52 +154,4 @@
}
return serverInstanceID;
}
-
- private boolean touchCoSTimeStamp(RunConfig rc, long stamp) {
- if (rc.getProject() == null) {
- return false;
- }
- Build build = rc.getMavenProject().getBuild();
- if (build == null || build.getOutputDirectory() == null) {
- return false;
- }
- File fl = new File(build.getOutputDirectory());
- fl = FileUtil.normalizeFile(fl);
- if (!fl.exists()) {
- //the project was not built
- return false;
- }
- File check = new File(fl, NB_COS);
- if (!check.exists()) {
- try {
- return check.createNewFile();
- } catch (IOException ex) {
- return false;
- }
- }
- return check.setLastModified(stamp);
- }
-
- public static boolean hasCoSTimeStamp(Project prj) {
- NbMavenProject nbprj = prj.getLookup().lookup(NbMavenProject.class);
- if (nbprj == null) {
- return false;
- }
- return new File(nbprj.getOutputDirectory(false), NB_COS).exists();
- }
-
-
- static class DLogger implements Deployment.Logger {
-
- private final OutputWriter logger;
-
- public DLogger(OutputWriter log) {
- logger = log;
- }
-
- @Override
- public void log(String string) {
- logger.println(string);
- }
- }
}
diff --git a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/J2EEPrerequisitesChecker.java b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/J2EEPrerequisitesChecker.java
--- a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/J2EEPrerequisitesChecker.java
+++ b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/J2EEPrerequisitesChecker.java
@@ -54,6 +54,8 @@
import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeModuleProvider;
import org.netbeans.modules.maven.api.NbMavenProject;
import org.netbeans.modules.maven.api.execute.LateBoundPrerequisitesChecker;
+import org.netbeans.modules.maven.j2ee.execution.DeploymentLogger;
+import static org.netbeans.modules.maven.j2ee.ui.customizer.impl.CustomizerRunWeb.PROP_ALWAYS_BUILD_BEFORE_RUNNING;
import org.netbeans.spi.project.ActionProvider;
import org.netbeans.spi.project.ProjectServiceProvider;
import org.openide.util.Exceptions;
@@ -86,6 +88,16 @@
@Override
public boolean checkRunConfig(RunConfig config) {
+ // To be able to skip standard run behavior we need to set this property
+ // with respect to the current CoS/DoS setting --> See issue 230565
+ Boolean alwaysBuild = (Boolean) config.getProject().getProjectDirectory().getAttribute(PROP_ALWAYS_BUILD_BEFORE_RUNNING);
+ if (alwaysBuild == null) {
+ alwaysBuild = Boolean.FALSE;
+ }
+
+ // If we don't want to build always, set skip.build property
+ config.setInternalProperty("skip.build", !alwaysBuild); //NOI18N
+
String actionName = config.getActionName();
if (!applicableActions.contains(actionName)) {
return true;
@@ -134,7 +146,7 @@
return true;
}
try {
- Deployment.getDefault ().undeploy(provider, false, new ExecutionChecker.DLogger(con.getInputOutput().getOut()));
+ Deployment.getDefault ().undeploy(provider, false, new DeploymentLogger(con.getInputOutput().getOut()));
} catch (DeploymentException ex) {
Exceptions.printStackTrace(ex);
}
diff --git a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/execution/AlternativeExecutorImpl.java b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/execution/AlternativeExecutorImpl.java
new file mode 100644
--- /dev/null
+++ b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/execution/AlternativeExecutorImpl.java
@@ -0,0 +1,86 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2013 Sun Microsystems, Inc.
+ */
+
+package org.netbeans.modules.maven.j2ee.execution;
+
+import org.netbeans.modules.maven.api.NbMavenProject;
+import org.netbeans.modules.maven.api.execute.ExecutionContext;
+import org.netbeans.modules.maven.api.execute.RunConfig;
+import org.netbeans.modules.maven.spi.execute.AlternativeExecutorImplementation;
+import org.netbeans.spi.project.ProjectServiceProvider;
+
+/**
+ * Implementation of the {@link AlternativeExecutorImplementation} enables to changes the default run/debug/profile
+ * behavior and does not force rebuild of application when one of these action is invoked.
+ *
+ *
+ * In combination with CoS/DoS feature this save time that was earlier needed for rebuild
+ * application started before actual redeployment.
+ *
+ *
+ * See issue 230565 for some details about why this was needed.
+ *
+ *
+ * This class is immutable and thus thread safe.
+ *
+ * @author Martin Janicek
+ * @since 2.97
+ */
+@ProjectServiceProvider(
+ service = {
+ AlternativeExecutorImplementation.class
+ },
+ projectType = {
+ "org-netbeans-modules-maven/" + NbMavenProject.TYPE_WAR,
+ "org-netbeans-modules-maven/" + NbMavenProject.TYPE_EJB,
+ "org-netbeans-modules-maven/" + NbMavenProject.TYPE_APPCLIENT,
+ "org-netbeans-modules-maven/" + NbMavenProject.TYPE_EAR,
+ "org-netbeans-modules-maven/" + NbMavenProject.TYPE_OSGI
+ }
+)
+public class AlternativeExecutorImpl implements AlternativeExecutorImplementation {
+
+ @Override
+ public boolean execute(RunConfig config, ExecutionContext executionContext) {
+ return DeploymentHelper.perform(config, executionContext);
+ }
+}
diff --git a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/execution/DeploymentHelper.java b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/execution/DeploymentHelper.java
new file mode 100644
--- /dev/null
+++ b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/execution/DeploymentHelper.java
@@ -0,0 +1,287 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2013 Sun Microsystems, Inc.
+ */
+
+package org.netbeans.modules.maven.j2ee.execution;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.concurrent.Callable;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.apache.maven.model.Build;
+import org.netbeans.api.project.Project;
+import org.netbeans.api.project.ProjectUtils;
+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.ServerInstance;
+import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeModuleProvider;
+import org.netbeans.modules.j2ee.deployment.plugins.api.ServerDebugInfo;
+import org.netbeans.modules.maven.api.execute.ExecutionContext;
+import org.netbeans.modules.maven.api.execute.RunConfig;
+import org.netbeans.modules.maven.api.execute.RunUtils;
+import static org.netbeans.modules.maven.j2ee.ExecutionChecker.DEV_NULL;
+import org.netbeans.modules.maven.j2ee.MavenJavaEEConstants;
+import org.netbeans.modules.maven.j2ee.OneTimeDeployment;
+import org.netbeans.modules.maven.j2ee.ui.customizer.impl.CustomizerRunWeb;
+import org.netbeans.modules.maven.j2ee.utils.MavenProjectSupport;
+import org.netbeans.modules.maven.spi.debug.MavenDebugger;
+import org.netbeans.modules.web.browser.spi.URLDisplayerImplementation;
+import org.openide.awt.HtmlBrowser;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileUtil;
+import org.openide.windows.OutputWriter;
+
+/**
+ * General helper class encapsulating behavior needed to perform deployment execution.
+ *
+ *
+ * This class is immutable and thus thread safe.
+ *
+ *
+ * @author Martin Janicek
+ */
+public final class DeploymentHelper {
+
+ private static final String MODULEURI = "netbeans.deploy.clientModuleUri"; //NOI18N
+ private static final String NB_COS = ".netbeans_automatic_build"; //NOI18N
+ private static final Logger LOGGER = Logger.getLogger(DeploymentHelper.class.getName());
+
+ public static final String CLIENTURLPART = "netbeans.deploy.clientUrlPart"; //NOI18N
+
+ private DeploymentHelper() {
+ }
+
+
+ /**
+ * Performs deploy based on the given arguments.
+ *
+ * @param config configuration
+ * @param executionContext execution context
+ * @return {@code true} if the execution was successful, {@code false} otherwise
+ */
+ public static boolean perform(final RunConfig config, final ExecutionContext executionContext) {
+ final Project project = config.getProject();
+
+ if (RunUtils.isCompileOnSaveEnabled(config)) {
+ //dump the nb java support's timestamp fil in output directory..
+ touchCoSTimeStamp(config, System.currentTimeMillis());
+ }
+ String moduleUri = config.getProperties().get(MODULEURI);
+ String clientUrlPart = config.getProperties().get(CLIENTURLPART);
+ if (clientUrlPart == null) {
+ clientUrlPart = ""; // NOI18N
+ }
+ boolean redeploy = isRedeploy(config);
+ boolean debugmode = isDebugMode(config);
+ boolean profilemode = isProfileMode(config);
+ boolean showInBrowser = showInBrowser(config);
+
+ FileUtil.refreshFor(FileUtil.toFile(project.getProjectDirectory()));
+ OutputWriter err = executionContext.getInputOutput().getErr();
+ OutputWriter out = executionContext.getInputOutput().getOut();
+ final J2eeModuleProvider jmp = project.getLookup().lookup(J2eeModuleProvider.class);
+ if (jmp == null) {
+ err.println();
+ err.println();
+ err.println("NetBeans: Application Server deployment not available for Maven project '" + ProjectUtils.getInformation(project).getDisplayName() + "'"); // NOI18N
+ return false;
+ }
+
+ String serverInstanceID = null;
+
+ // First check if the one-time deployment server is set
+ OneTimeDeployment oneTimeDeployment = project.getLookup().lookup(OneTimeDeployment.class);
+ if (oneTimeDeployment != null) {
+ serverInstanceID = oneTimeDeployment.getServerInstanceId();
+ }
+
+ if (serverInstanceID == null) {
+ serverInstanceID = jmp.getServerInstanceID();
+ if (DEV_NULL.equals(serverInstanceID) || serverInstanceID == null) {
+ err.println();
+ err.println();
+ err.println("NetBeans: No suitable Deployment Server is defined for the project or globally."); // NOI18N
+ return false;
+ }
+ }
+ ServerInstance si = Deployment.getDefault().getServerInstance(serverInstanceID);
+ try {
+ out.println("NetBeans: Deploying on " + (si != null ? si.getDisplayName() : serverInstanceID)); //NOI18N - no localization in maven build now.
+ } catch (InstanceRemovedException ex) {
+ out.println("NetBeans: Deploying on " + serverInstanceID); // NOI18N
+ }
+ try {
+ out.println(" profile mode: " + profilemode); // NOI18N
+ out.println(" debug mode: " + debugmode); // NOI18N
+ out.println(" force redeploy: " + redeploy); //NOI18N
+
+
+ Deployment.Mode mode = Deployment.Mode.RUN;
+ if (debugmode) {
+ mode = Deployment.Mode.DEBUG;
+ } else if (profilemode) {
+ mode = Deployment.Mode.PROFILE;
+ }
+
+ Callable debuggerHook = null;
+ if (debugmode) {
+ debuggerHook = new Callable() {
+
+ @Override
+ public Void call() throws Exception {
+ ServerDebugInfo sdi = jmp.getServerDebugInfo();
+
+ if (sdi != null) { //fix for bug 57854, this can be null
+ String h = sdi.getHost();
+ String transport = sdi.getTransport();
+ String address;
+
+ if (transport.equals(ServerDebugInfo.TRANSPORT_SHMEM)) {
+ address = sdi.getShmemName();
+ } else {
+ address = Integer.toString(sdi.getPort());
+ }
+ MavenDebugger deb = project.getLookup().lookup(MavenDebugger.class);
+ try {
+ deb.attachDebugger(executionContext.getInputOutput(), "Debug Deployed app", transport, h, address); // NOI18N
+ } catch (Exception ex) {
+ // See issue #235796 --> We were not able to attach debugger because
+ // it's already attached, BUT we still want to deploy the application
+ LOGGER.log(Level.FINE, "Exception occured while trying to attach debugger", ex); //NOI18N
+ }
+ }
+ return null;
+ }
+ };
+
+ }
+
+ String clientUrl = Deployment.getDefault().deploy(jmp, mode, moduleUri, clientUrlPart, redeploy, new DeploymentLogger(out), debuggerHook);
+ if (clientUrl != null) {
+ if (showInBrowser) {
+ URL url = new URL(clientUrl);
+ URLDisplayerImplementation urlDisplayer = project.getLookup().lookup(URLDisplayerImplementation.class);
+ if (urlDisplayer != null) {
+ URL appRoot = url;
+ if (clientUrlPart.length() > 0 && clientUrl.endsWith(clientUrlPart)) {
+ appRoot = new URL(clientUrl.substring(0, clientUrl.length() - clientUrlPart.length()));
+ }
+ urlDisplayer.showURL(appRoot, url, project.getProjectDirectory());
+ } else {
+ HtmlBrowser.URLDisplayer.getDefault().showURL(url);
+ }
+ }
+ }
+ } catch (Deployment.DeploymentException | MalformedURLException ex) {
+ LOGGER.log(Level.FINE, "Exception occured wile deploying to Application Server.", ex); //NOI18N
+ }
+
+ // Reset the value of the one-time server
+ if (oneTimeDeployment != null) {
+ oneTimeDeployment.reset();
+ MavenProjectSupport.changeServer(project, false);
+ }
+ return true;
+ }
+
+ private static boolean isRedeploy(RunConfig config) {
+ return readBooleanValue(config, MavenJavaEEConstants.ACTION_PROPERTY_DEPLOY_REDEPLOY, true);
+ }
+
+ private static boolean isDebugMode(RunConfig config) {
+ return readBooleanValue(config, MavenJavaEEConstants.ACTION_PROPERTY_DEPLOY_DEBUG_MODE, false);
+ }
+
+ private static boolean isProfileMode(RunConfig config) {
+ return readBooleanValue(config, "netbeans.deploy.profilemode", false); //NOI18N
+ }
+
+ private static boolean showInBrowser(RunConfig config) {
+ if (!readBooleanValue(config, MavenJavaEEConstants.ACTION_PROPERTY_DEPLOY_OPEN, true)) {
+ return false;
+ }
+
+ FileObject projectDir = config.getProject().getProjectDirectory();
+ if (projectDir != null) {
+ String browser = (String) projectDir.getAttribute(CustomizerRunWeb.PROP_SHOW_IN_BROWSER);
+ if (browser != null && Boolean.parseBoolean(browser)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static boolean readBooleanValue(RunConfig config, String key, boolean defaultValue) {
+ String value = config.getProperties().get(key);
+ if (value != null) {
+ return Boolean.parseBoolean(value);
+ }
+ return defaultValue;
+ }
+
+ private static boolean touchCoSTimeStamp(RunConfig rc, long stamp) {
+ if (rc.getProject() == null) {
+ return false;
+ }
+ Build build = rc.getMavenProject().getBuild();
+ if (build == null || build.getOutputDirectory() == null) {
+ return false;
+ }
+ File fl = new File(build.getOutputDirectory());
+ fl = FileUtil.normalizeFile(fl);
+ if (!fl.exists()) {
+ //the project was not built
+ return false;
+ }
+ File check = new File(fl, NB_COS);
+ if (!check.exists()) {
+ try {
+ return check.createNewFile();
+ } catch (IOException ex) {
+ return false;
+ }
+ }
+ return check.setLastModified(stamp);
+ }
+}
diff --git a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/execution/DeploymentLogger.java b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/execution/DeploymentLogger.java
new file mode 100644
--- /dev/null
+++ b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/execution/DeploymentLogger.java
@@ -0,0 +1,69 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2013 Sun Microsystems, Inc.
+ */
+
+package org.netbeans.modules.maven.j2ee.execution;
+
+import org.netbeans.modules.j2ee.deployment.devmodules.api.Deployment;
+import org.openide.windows.OutputWriter;
+
+/**
+ * Simple implementation of the {@link Deployment.Logger} used by the infrastructure to log deployment messages.
+ *
+ *
+ * This class is immutable and thus thread safe.
+ *
+ *
+ * @author Martin Janicek
+ */
+public class DeploymentLogger implements Deployment.Logger {
+
+ private final OutputWriter logger;
+
+ public DeploymentLogger(OutputWriter logger) {
+ this.logger = logger;
+ }
+
+ @Override
+ public void log(String string) {
+ logger.println(string);
+ }
+}
diff --git a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/customizer/BaseRunCustomizer.java b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/customizer/BaseRunCustomizer.java
--- a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/customizer/BaseRunCustomizer.java
+++ b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/customizer/BaseRunCustomizer.java
@@ -57,8 +57,12 @@
import org.netbeans.modules.maven.j2ee.ExecutionChecker;
import org.netbeans.modules.maven.j2ee.utils.Server;
import static org.netbeans.modules.maven.j2ee.ui.customizer.Bundle.*;
+import org.netbeans.modules.maven.j2ee.ui.util.WarningPanel;
+import org.netbeans.modules.maven.j2ee.ui.util.WarningPanelSupport;
import org.netbeans.modules.maven.j2ee.utils.MavenProjectSupport;
import org.netbeans.modules.maven.j2ee.utils.ServerUtils;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle.Messages;
@@ -79,15 +83,46 @@
this.project = project;
}
+ @Messages({
+ "WARNING_ChangingAutomaticBuild=You are trying to turn deploy on save feature off. Please be aware about "
+ + "possible consequences. Your files won't be redeployed immediately after the save which means you "
+ + "will be responsible for redeployment of the application content every time when you want to see actual "
+ + "state of sources on server.
Because of that it is highly recommended to turn option called \"Always "
+ + "perform build\" on, so you will need only to Run application and NetBeans will take care about automatic rebuild "
+ + "of sources before deployment.."
+ })
protected void initDeployOnSave(final JCheckBox dosCheckBox, final JLabel dosDescription) {
boolean isDoS = MavenProjectSupport.isDeployOnSave(project);
- deployOnSaveUpdater = CheckBoxUpdater.create(dosCheckBox, isDoS, new CheckBoxUpdater.Store() {
+
+ CheckBoxUpdater.Store store = new CheckBoxUpdater.Store() {
@Override
public void storeValue(boolean value) {
MavenProjectSupport.setDeployOnSave(project, value);
}
- });
+ };
+
+ CheckBoxUpdater.Verify verifier = new CheckBoxUpdater.Verify() {
+
+ @Override
+ public boolean verifyValue(boolean value) {
+ if (!value && WarningPanelSupport.isAutomaticBuildWarningActivated()) {
+ WarningPanel panel = new WarningPanel(WARNING_ChangingAutomaticBuild());
+ NotifyDescriptor dd = new NotifyDescriptor.Confirmation(panel, NotifyDescriptor.OK_CANCEL_OPTION);
+ DialogDisplayer.getDefault().notify(dd);
+
+ if (dd.getValue() == NotifyDescriptor.CANCEL_OPTION) {
+ return false;
+ }
+ if (panel.disabledWarning()) {
+ WarningPanelSupport.dontShowAutomaticBuildWarning();
+ }
+ }
+ return true;
+ }
+ };
+
+ deployOnSaveUpdater = CheckBoxUpdater.create(dosCheckBox, isDoS, store, verifier);
addAncestorListener(new AncestorListener() {
diff --git a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/customizer/CheckBoxUpdater.java b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/customizer/CheckBoxUpdater.java
--- a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/customizer/CheckBoxUpdater.java
+++ b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/customizer/CheckBoxUpdater.java
@@ -66,6 +66,7 @@
*
* @see ComboBoxUpdater
* @see Store
+ * @see Verify
*
* @author Martin Janicek
*/
@@ -89,8 +90,27 @@
void storeValue(boolean value);
}
+ /**
+ * Interface used by the updater to verify if the new value can be stored in the combo box.
+ *
+ *
+ * Please be aware that if this method returns {@code false}, the {@link Store#storeValue(java.lang.Object)}
+ * won't be called.
+ */
+ public interface Verify {
+
+ /**
+ * Verifies value given by the parameter.
+ *
+ * @param value to be verified
+ * @return {@code true} if the value is OK, {@code false} otherwise
+ */
+ boolean verifyValue(boolean value);
+ }
+
private final Store store;
+ private final Verify verifier;
private final JCheckBox checkBox;
private final boolean defaultValue;
@@ -103,18 +123,40 @@
* be called.
*
* @param checkBox we want to decorate
+ * @param defaultValue default value for the check box
* @param store implementation used to store check box value
- * @param defaultValue default value for the check box
* @return instance of the {@link CheckBoxUpdater}
*/
public static CheckBoxUpdater create(JCheckBox checkBox, boolean defaultValue, Store store) {
- CheckBoxUpdater instance = new CheckBoxUpdater(checkBox, defaultValue, store);
+ return create(checkBox, defaultValue, store, null);
+ }
+
+ /**
+ * Creates an instance of the {@link CheckBoxUpdater}.
+ *
+ *
+ * The check box will be initialized using the given default value. If the client
+ * want to store current value, {@link CheckBoxUpdater#storeValue()} method has to
+ * be called.
+ *
+ *
+ * For the value verification, pass instance of {@link CheckBoxUpdater.Verify} which
+ * will be called before the new value will be set into the check box.
+ *
+ * @param checkBox we want to decorate
+ * @param defaultValue default value for the check box
+ * @param store implementation used to store check box value
+ * @param verifier implementation used to verify new check box value
+ * @return instance of the {@link CheckBoxUpdater}
+ */
+ public static CheckBoxUpdater create(JCheckBox checkBox, boolean defaultValue, Store store, Verify verifier) {
+ CheckBoxUpdater instance = new CheckBoxUpdater(checkBox, defaultValue, store, verifier);
instance.checkBox.addItemListener(instance);
return instance;
}
- private CheckBoxUpdater(JCheckBox checkBox, boolean defaultValue, Store store) {
+ private CheckBoxUpdater(JCheckBox checkBox, boolean defaultValue, Store store, Verify verifier) {
assert (checkBox != null);
assert (store != null);
@@ -122,6 +164,7 @@
this.checkBox.setSelected(defaultValue);
this.defaultValue = defaultValue;
this.store = store;
+ this.verifier = verifier;
setValue(defaultValue);
}
@@ -138,11 +181,27 @@
@Override
public void itemStateChanged(ItemEvent e) {
- setValue(checkBox.isSelected());
+ if (ItemEvent.DESELECTED == e.getStateChange()) {
+ boolean isSelected = checkBox.isSelected();
+ if (verifier != null) {
+ if (verifier.verifyValue(isSelected)) {
+ setValue(isSelected);
+ }
+ } else {
+ // If there is no defined verifier, simply change the value
+ setValue(isSelected);
+ }
+ }
}
@NbBundle.Messages("MSG_CheckBox_Value_Changed=This value had been changed from the default one")
private void setValue(boolean value) {
+ // We don't want to notify listeners about state changes made in this method
+ ItemListener[] itemListeners = checkBox.getItemListeners();
+ for (ItemListener listener : itemListeners) {
+ checkBox.removeItemListener(listener);
+ }
+
if (defaultValue == value) {
checkBox.setFont(checkBox.getFont().deriveFont(Font.PLAIN));
checkBox.setToolTipText(null);
@@ -150,5 +209,11 @@
checkBox.setFont(checkBox.getFont().deriveFont(Font.BOLD));
checkBox.setToolTipText(MSG_CheckBox_Value_Changed());
}
+ checkBox.setSelected(value);
+
+ // Register listeners back to have them consistent
+ for (ItemListener listener : itemListeners) {
+ checkBox.addItemListener(listener);
+ }
}
}
diff --git a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/customizer/impl/Bundle.properties b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/customizer/impl/Bundle.properties
--- a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/customizer/impl/Bundle.properties
+++ b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/customizer/impl/Bundle.properties
@@ -53,3 +53,6 @@
CustomizerRunWeb.jCBCopyStaticResources.toolTipText=If selected, static resources (like jsp, html etc.) are copied to the target directory when you save them.
CustomizerRunWeb.jCBCopyStaticResources.text=Copy Static Resources on Save
CustomizerRunWeb.jCBDeployOnSave.text=D&eploy on Save
+CustomizerRunWeb.jCBAlwaysBuild.toolTipText=If selected, IDE will perform mvn package everytime when running application
+CustomizerRunWeb.jCBAlwaysBuild.text=Always perform build before running application
+CustomizerRunWeb.btnLearnMore.text=Learn More about Deploy On Save feature in Maven projects
diff --git a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/customizer/impl/CustomizerRunWeb.form b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/customizer/impl/CustomizerRunWeb.form
--- a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/customizer/impl/CustomizerRunWeb.form
+++ b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/customizer/impl/CustomizerRunWeb.form
@@ -38,17 +38,24 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -94,6 +101,10 @@
+
+
+
+
@@ -234,5 +245,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/customizer/impl/CustomizerRunWeb.java b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/customizer/impl/CustomizerRunWeb.java
--- a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/customizer/impl/CustomizerRunWeb.java
+++ b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/customizer/impl/CustomizerRunWeb.java
@@ -43,7 +43,12 @@
package org.netbeans.modules.maven.j2ee.ui.customizer.impl;
import java.awt.Component;
+import java.awt.Cursor;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
@@ -83,6 +88,7 @@
import org.netbeans.spi.project.ActionProvider;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
+import org.openide.awt.HtmlBrowser;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
@@ -95,11 +101,13 @@
public class CustomizerRunWeb extends BaseRunCustomizer {
public static final String PROP_SHOW_IN_BROWSER = "netbeans.deploy.showBrowser"; //NOI18N
+ public static final String PROP_ALWAYS_BUILD_BEFORE_RUNNING = "netbeans.always.build"; // NOI18N
private static final Set WEB_PROFILES;
private static final Set FULL_PROFILES;
private final CheckBoxUpdater copyStaticResourcesUpdater;
private final CheckBoxUpdater showBrowserUpdater;
+ private final CheckBoxUpdater alwaysBuildUpdater;
private final ComboBoxUpdater versionUpdater;
private final boolean noServer;
@@ -141,6 +149,18 @@
super(handle, project);
initComponents();
+ btnLearnMore.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+ btnLearnMore.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ try {
+ HtmlBrowser.URLDisplayer.getDefault().showURL(new URL("http://wiki.netbeans.org/FaqDeployOnSave"));
+ } catch (MalformedURLException ex) {
+ Exceptions.printStackTrace(ex);
+ }
+ }
+ });
+
module = WebModule.getWebModule(project.getProjectDirectory());
if (module != null) {
contextPathTField.setText(module.getContextPath());
@@ -178,6 +198,26 @@
}
});
+ Boolean alwaysBuild = (Boolean) project.getProjectDirectory().getAttribute(PROP_ALWAYS_BUILD_BEFORE_RUNNING);
+ if (alwaysBuild == null) {
+ alwaysBuild = Boolean.FALSE;
+ }
+ alwaysBuildUpdater = CheckBoxUpdater.create(jCBAlwaysBuild, alwaysBuild, new CheckBoxUpdater.Store() {
+
+ @Override
+ public void storeValue(boolean value) {
+ try {
+ if (value) {
+ project.getProjectDirectory().setAttribute(PROP_ALWAYS_BUILD_BEFORE_RUNNING, true);
+ } else {
+ project.getProjectDirectory().setAttribute(PROP_ALWAYS_BUILD_BEFORE_RUNNING, false);
+ }
+ } catch (IOException ex) {
+ Exceptions.printStackTrace(ex);
+ }
+ }
+ });
+
versionUpdater = createVersionUpdater(J2eeModule.Type.WAR);
}
@@ -198,6 +238,7 @@
serverUpdater.storeValue();
versionUpdater.storeValue();
+ alwaysBuildUpdater.storeValue();
deployOnSaveUpdater.storeValue();
copyStaticResourcesUpdater.storeValue();
@@ -297,7 +338,7 @@
public boolean verifyValue(Object value) {
if (WarningPanelSupport.isJavaEEChangeWarningActivated()) {
WarningPanel panel = new WarningPanel(WARNING_ChangingJavaEEVersion());
- NotifyDescriptor dd = new NotifyDescriptor.Message(panel, NotifyDescriptor.OK_CANCEL_OPTION);
+ NotifyDescriptor dd = new NotifyDescriptor.Confirmation(panel, NotifyDescriptor.OK_CANCEL_OPTION);
DialogDisplayer.getDefault().notify(dd);
if (dd.getValue() == NotifyDescriptor.CANCEL_OPTION) {
@@ -402,6 +443,8 @@
browserLabel = new javax.swing.JLabel();
jCBBrowser = createBrowserComboBox();
jCBCopyStaticResources = new javax.swing.JCheckBox();
+ jCBAlwaysBuild = new javax.swing.JCheckBox();
+ btnLearnMore = new javax.swing.JButton();
org.openide.awt.Mnemonics.setLocalizedText(serverLabel, org.openide.util.NbBundle.getMessage(CustomizerRunWeb.class, "LBL_Server")); // NOI18N
@@ -438,6 +481,14 @@
org.openide.awt.Mnemonics.setLocalizedText(jCBCopyStaticResources, org.openide.util.NbBundle.getMessage(CustomizerRunWeb.class, "CustomizerRunWeb.jCBCopyStaticResources.text")); // NOI18N
jCBCopyStaticResources.setToolTipText(org.openide.util.NbBundle.getMessage(CustomizerRunWeb.class, "CustomizerRunWeb.jCBCopyStaticResources.toolTipText")); // NOI18N
+ org.openide.awt.Mnemonics.setLocalizedText(jCBAlwaysBuild, org.openide.util.NbBundle.getMessage(CustomizerRunWeb.class, "CustomizerRunWeb.jCBAlwaysBuild.text")); // NOI18N
+ jCBAlwaysBuild.setToolTipText(org.openide.util.NbBundle.getMessage(CustomizerRunWeb.class, "CustomizerRunWeb.jCBAlwaysBuild.toolTipText")); // NOI18N
+
+ org.openide.awt.Mnemonics.setLocalizedText(btnLearnMore, org.openide.util.NbBundle.getMessage(CustomizerRunWeb.class, "CustomizerRunWeb.btnLearnMore.text")); // NOI18N
+ btnLearnMore.setBorderPainted(false);
+ btnLearnMore.setContentAreaFilled(false);
+ btnLearnMore.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT);
+
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
@@ -461,15 +512,20 @@
.addComponent(txtRelativeUrl, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jCBBrowser, javax.swing.GroupLayout.Alignment.TRAILING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
.addGroup(layout.createSequentialGroup()
+ .addComponent(jCBDeployOnSave)
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addGroup(layout.createSequentialGroup()
.addGap(21, 21, 21)
.addComponent(dosDescription, javax.swing.GroupLayout.DEFAULT_SIZE, 609, Short.MAX_VALUE))
.addGroup(layout.createSequentialGroup()
- .addComponent(jCBDeployOnSave)
- .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
- .addGroup(layout.createSequentialGroup()
- .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
- .addComponent(jCBshowBrowser, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(jCBCopyStaticResources, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addGap(21, 21, 21)
+ .addComponent(btnLearnMore, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addComponent(jCBAlwaysBuild)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addComponent(jCBshowBrowser, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(jCBCopyStaticResources, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
.addGap(0, 0, Short.MAX_VALUE))))
);
layout.setVerticalGroup(
@@ -505,6 +561,10 @@
.addComponent(jCBDeployOnSave)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(dosDescription, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(jCBAlwaysBuild)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(btnLearnMore, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
@@ -543,9 +603,11 @@
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel browserLabel;
+ private javax.swing.JButton btnLearnMore;
private javax.swing.JLabel contextPathLabel;
private javax.swing.JTextField contextPathTField;
private javax.swing.JLabel dosDescription;
+ private javax.swing.JCheckBox jCBAlwaysBuild;
private javax.swing.JComboBox jCBBrowser;
private javax.swing.JCheckBox jCBCopyStaticResources;
private javax.swing.JCheckBox jCBDeployOnSave;
diff --git a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/util/WarningPanel.form b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/util/WarningPanel.form
--- a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/util/WarningPanel.form
+++ b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/util/WarningPanel.form
@@ -35,7 +35,7 @@
-
+
diff --git a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/util/WarningPanel.java b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/util/WarningPanel.java
--- a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/util/WarningPanel.java
+++ b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/util/WarningPanel.java
@@ -92,7 +92,7 @@
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
- .addComponent(lblText, javax.swing.GroupLayout.DEFAULT_SIZE, 137, Short.MAX_VALUE)
+ .addComponent(lblText, javax.swing.GroupLayout.DEFAULT_SIZE, 270, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(cbNextTime))
);
diff --git a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/util/WarningPanelSupport.java b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/util/WarningPanelSupport.java
--- a/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/util/WarningPanelSupport.java
+++ b/maven.j2ee/src/org/netbeans/modules/maven/j2ee/ui/util/WarningPanelSupport.java
@@ -51,7 +51,8 @@
*/
public final class WarningPanelSupport {
- private static final String JAVA_EE_VERSION_CHANGE = "showJavaEEVersionChangeWarning"; //NOI18N
+ private static final String JAVA_EE_VERSION_CHANGE = "showJavaEEVersionChangeWarning"; // NOI18N
+ private static final String AUTOMATIC_BUILD = "automaticBuildWarning"; // NOI18N
private WarningPanelSupport() {
}
@@ -67,4 +68,12 @@
public static void dontShowJavaEEChangeWarning() {
getPreferences().putBoolean(JAVA_EE_VERSION_CHANGE, false);
}
+
+ public static boolean isAutomaticBuildWarningActivated() {
+ return getPreferences().getBoolean(AUTOMATIC_BUILD, true);
+ }
+
+ public static void dontShowAutomaticBuildWarning() {
+ getPreferences().putBoolean(AUTOMATIC_BUILD, false);
+ }
}
diff --git a/maven/manifest.mf b/maven/manifest.mf
--- a/maven/manifest.mf
+++ b/maven/manifest.mf
@@ -1,6 +1,6 @@
Manifest-Version: 1.0
OpenIDE-Module: org.netbeans.modules.maven/2
-OpenIDE-Module-Specification-Version: 2.96
+OpenIDE-Module-Specification-Version: 2.97
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/maven/Bundle.properties
OpenIDE-Module-Layer: org/netbeans/modules/maven/layer.xml
AutoUpdate-Show-In-Client: false
diff --git a/maven/nbproject/project.xml b/maven/nbproject/project.xml
--- a/maven/nbproject/project.xml
+++ b/maven/nbproject/project.xml
@@ -478,14 +478,15 @@
org.javeleon.netbeans
-
org.nbheaven.sqe.core.maven
org.nbheaven.sqe.core.maven3
+ org.netbeans.modules.android.maven
org.netbeans.modules.apisupport.installer.maven
org.netbeans.modules.groovy.support
org.netbeans.modules.hudson.maven
org.netbeans.modules.jbi.fuji.support
org.netbeans.modules.kenai.maven
+ org.netbeans.modules.ko4j.debugging
org.netbeans.modules.maven.apisupport
org.netbeans.modules.maven.checkstyle
org.netbeans.modules.maven.coverage
@@ -503,16 +504,11 @@
org.netbeans.modules.maven.repository
org.netbeans.modules.maven.samples
org.netbeans.modules.maven.spring
+ org.netbeans.modules.maven.util
+ org.netbeans.modules.scala.maven
org.netbeans.modules.selenium.maven
- org.netbeans.modules.ko4j.debugging
org.netbeans.modules.testng.maven
-
- org.netbeans.modules.android.maven
-
- org.netbeans.modules.scala.maven
-
org.vaadin.netbeans.maven
- org.netbeans.modules.maven.util
org.netbeans.modules.maven.api
org.netbeans.modules.maven.api.archetype
org.netbeans.modules.maven.api.classpath
@@ -529,6 +525,7 @@
org.netbeans.modules.maven.spi.cos
org.netbeans.modules.maven.spi.customizer
org.netbeans.modules.maven.spi.debug
+ org.netbeans.modules.maven.spi.execute
org.netbeans.modules.maven.spi.grammar
org.netbeans.modules.maven.spi.nodes
org.netbeans.modules.maven.spi.queries
diff --git a/maven/src/org/netbeans/modules/maven/api/execute/AlternativeExecutor.java b/maven/src/org/netbeans/modules/maven/api/execute/AlternativeExecutor.java
new file mode 100644
--- /dev/null
+++ b/maven/src/org/netbeans/modules/maven/api/execute/AlternativeExecutor.java
@@ -0,0 +1,80 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2013 Sun Microsystems, Inc.
+ */
+
+package org.netbeans.modules.maven.api.execute;
+
+import org.netbeans.modules.maven.spi.execute.AlternativeExecutorImplementation;
+
+/**
+ * API for alternative execution of Maven Run/Debug/Profile actions.
+ *
+ * @see AlternativeExecutorImplementation
+ *
+ * @author Martin Janicek
+ * @since 2.97
+ */
+public final class AlternativeExecutor {
+
+ private AlternativeExecutor() {
+ }
+
+ /**
+ * Perform an alternative execution.
+ *
+ *
+ * Using the given {@link RunConfig}, finds {@link AlternativeExecutorImplementation}
+ * registered for the project and performs it's execute method.
+ *
+ * @param config configuration
+ * @param context execution context
+ * @return {@code true} if the execution was successful, {@code false} otherwise
+ */
+ public static boolean execute(RunConfig config, ExecutionContext context) {
+ AlternativeExecutorImplementation alternativeExecutor = config.getProject().getLookup().lookup(AlternativeExecutorImplementation.class);
+ if (alternativeExecutor != null) {
+ if (alternativeExecutor.execute(config, context)) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/maven/src/org/netbeans/modules/maven/cos/CosChecker.java b/maven/src/org/netbeans/modules/maven/cos/CosChecker.java
--- a/maven/src/org/netbeans/modules/maven/cos/CosChecker.java
+++ b/maven/src/org/netbeans/modules/maven/cos/CosChecker.java
@@ -158,13 +158,23 @@
touchProject(openprj);
}
//new style Compile on Save
- checkRunMainClass(config, con);
+ if (!checkRunMainClass(config, con)) {
+ return false;
+ }
checkRunTest(config, con);
}
return true;
}
- private void checkRunMainClass(final RunConfig config, ExecutionContext con) {
+ /**
+ * Returns {@code false} if execution should skip standard build phases.
+ *
+ * @param config run configuration
+ * @param con execution context
+ * @return {@code false} if execution should skip standard build phases,
+ * {@code true} otherwise
+ */
+ private boolean checkRunMainClass(final RunConfig config, ExecutionContext con) {
final String actionName = config.getActionName();
//compile on save stuff
if (RunUtils.isCompileOnSaveEnabled(config)) {
@@ -179,13 +189,13 @@
//check the COS timestamp against critical files (pom.xml)
// if changed, don't do COS.
if (checkImportantFiles(stamp, config)) {
- return;
+ return true;
}
//check the COS timestamp against resources etc.
//if changed, perform part of the maven build. (or skip COS)
for (CompileOnSaveSkipper skipper : Lookup.getDefault().lookupAll(CompileOnSaveSkipper.class)) {
if (skipper.skip(config, false, stamp)) {
- return;
+ return true;
}
}
@@ -193,6 +203,14 @@
if ((javarunnerCheckprops != null && javarunnerCheckprops.containsKey(USE_OLD_COS_EXECUTION)) || config.getProperties().containsKey(USE_OLD_COS_EXECUTION)) {
LOG.fine("use.old.cos.execution found, using JavaRunner to execute.");
} else {
+ // #230565
+ Object skipBuild = config.getInternalProperties().get("skip.build"); //NOI18N
+ if (skipBuild instanceof Boolean && (Boolean) skipBuild) {
+ if (!AlternativeExecutor.execute(config, con)) {
+ return false;
+ }
+ }
+
//now attempt to extract
if (config instanceof BeanRunConfig) {
BeanRunConfig brc = (BeanRunConfig) config;
@@ -217,6 +235,7 @@
}
}
}
+ return true;
}
private void checkRunTest(final RunConfig config, ExecutionContext con) {
diff --git a/maven/src/org/netbeans/modules/maven/spi/execute/AlternativeExecutorImplementation.java b/maven/src/org/netbeans/modules/maven/spi/execute/AlternativeExecutorImplementation.java
new file mode 100644
--- /dev/null
+++ b/maven/src/org/netbeans/modules/maven/spi/execute/AlternativeExecutorImplementation.java
@@ -0,0 +1,87 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2013 Sun Microsystems, Inc.
+ */
+
+package org.netbeans.modules.maven.spi.execute;
+
+import org.netbeans.modules.maven.api.execute.AlternativeExecutor;
+import org.netbeans.modules.maven.api.execute.ExecutionContext;
+import org.netbeans.modules.maven.api.execute.RunConfig;
+
+/**
+ * Alternative executor enables to rewrite default way how run/debug/profile actions
+ * are performed.
+ *
+ *
+ * This can be useful in cases when we don't need to execute standard run behavior.
+ * For example when re-running Maven Web application with enabled CoS/DoS, we don't
+ * want to rebuild whole project every-time and simply re-opening index.html is enough.
+ *
+ *
+ * If the project want to use {@link AlternativeExecutorImplementation} it should register
+ * it in it's project {@link Lookup}.
+ *
+ *
+ * This class should not be used directly. Use {@link AlternativeExecutor} API class instead.
+ *
+ *
+ * See issue 230565 for some details about why this was needed in the first place.
+ *
+ * @see AlternativeExecutor
+ *
+ * @author Martin Janicek
+ * @since 2.97
+ */
+public interface AlternativeExecutorImplementation {
+
+ /**
+ * Perform an alternative execution.
+ *
+ *
+ * SPI client should perform whatever he wants to do instead of the default execution behavior.
+ *
+ * @param config configuration
+ * @param executionContext execution context
+ * @return {@code true} if the execution was successful, {@code false} otherwise
+ */
+ boolean execute(RunConfig config, ExecutionContext executionContext);
+
+}