Index: plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/server/xpl/LocalCopyCallback.java =================================================================== --- plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/server/xpl/LocalCopyCallback.java (revision 37255) +++ plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/server/xpl/LocalCopyCallback.java (working copy) @@ -55,7 +55,7 @@ monitor.beginTask("Copying " + relativePath.toString(), 100); //$NON-NLS-1$ File file = PublishUtil.getFile(mf); DeployableServerBehavior beh = ServerConverter.getDeployableServerBehavior(server); - shouldRestartModule |= beh.changedFileRequiresModuleRestart(file); + shouldRestartModule |= beh.changedFileRequiresModuleRestart(mf); if( file != null ) { InputStream in = null; try { Index: plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/server/internal/v7/DelegatingJBoss7ServerBehavior.java =================================================================== --- plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/server/internal/v7/DelegatingJBoss7ServerBehavior.java (revision 37255) +++ plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/server/internal/v7/DelegatingJBoss7ServerBehavior.java (working copy) @@ -28,6 +28,7 @@ import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.core.model.IProcess; import org.eclipse.wst.server.core.IModule; +import org.eclipse.wst.server.core.model.IModuleFile; import org.jboss.ide.eclipse.as.core.JBossServerCorePlugin; import org.jboss.ide.eclipse.as.core.Messages; import org.jboss.ide.eclipse.as.core.extensions.events.IEventCodes; @@ -188,10 +189,4 @@ DeploymentMarkerUtils.addDoDeployMarker(getOrCreatePublishMethod(), getServer(), paths, monitor); } - @Override - public boolean changedFileRequiresModuleRestart(File file) { - return super.changedFileRequiresModuleRestart(file); - //return true; - } - } Index: plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/server/internal/v7/JBoss7JSTPublisher.java =================================================================== --- plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/server/internal/v7/JBoss7JSTPublisher.java (revision 37255) +++ plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/server/internal/v7/JBoss7JSTPublisher.java (working copy) @@ -69,6 +69,7 @@ protected void markModuleRequiresRestart(IPath deployPath, IModule[] moduleTree, IJBossServerPublishMethod method, IPublishCopyCallbackHandler handler) throws CoreException { boolean useAS7Behavior = DeploymentMarkerUtils.supportsJBoss7MarkerDeployment(server.getServer()); + System.out.println("Mark " + deployPath + " for restart"); //$NON-NLS-1$//$NON-NLS-2$ if( !useAS7Behavior) { // Simply touch the descriptor as needed JSTPublisherXMLToucher.getInstance().touch(deployPath, Index: plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/server/internal/DeployableServerBehavior.java =================================================================== --- plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/server/internal/DeployableServerBehavior.java (revision 37255) +++ plugins/org.jboss.ide.eclipse.as.core/jbosscore/org/jboss/ide/eclipse/as/core/server/internal/DeployableServerBehavior.java (working copy) @@ -13,6 +13,8 @@ import java.io.File; import java.util.HashMap; import java.util.List; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; @@ -23,6 +25,7 @@ import org.eclipse.wst.server.core.IServer; import org.eclipse.wst.server.core.IServerListener; import org.eclipse.wst.server.core.ServerEvent; +import org.eclipse.wst.server.core.model.IModuleFile; import org.eclipse.wst.server.core.model.IModuleResourceDelta; import org.eclipse.wst.server.core.model.ServerBehaviourDelegate; import org.jboss.ide.eclipse.as.core.JBossServerCorePlugin; @@ -38,8 +41,31 @@ */ public class DeployableServerBehavior extends ServerBehaviourDelegate { + public static final String ORG_JBOSS_TOOLS_AS_RESTART_FILE_PATTERN = "org.jboss.tools.as.restartFilePattern"; //$NON-NLS-1$ + + // kept static to avoid overhead of pattern compilation + final private static Pattern defaultFilePattern = Pattern.compile("\\.jar$", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$ + + // contains the pattern to use to recognize if files deployed needs to result in restart + // can be set via system property "org.jboss.tools.as.restartFilePattern" but should eventually be made + // available via server settings. + private Pattern restartFilePattern = null; + public DeployableServerBehavior() { + String systemPattern = System.getProperty(ORG_JBOSS_TOOLS_AS_RESTART_FILE_PATTERN,null); + + if(systemPattern == null) { + restartFilePattern = defaultFilePattern; + } else { + try { + setRestartFilePattern(systemPattern); + } catch(PatternSyntaxException pse) { + JBossServerCorePlugin.getDefault(); + JBossServerCorePlugin.log("Could not set restart file pattern to: " + systemPattern, pse); //$NON-NLS-1$ + } + } } + public void stop(boolean force) { setServerStopped(); // simple enough @@ -161,6 +187,7 @@ * Much of this can be changed once eclipse bug 231956 is fixed */ protected int serverStateVal; + protected int getServerStateVal() { return serverStateVal; } @@ -199,9 +226,18 @@ } ); } - public boolean changedFileRequiresModuleRestart(File file) { - if( file.getName().toLowerCase().endsWith(".jar")) //$NON-NLS-1$ - return true; - return false; + public boolean changedFileRequiresModuleRestart(IModuleFile file) { + if (restartFilePattern != null) { + // using find over matches to make it a substring search by default and avoid having to specify .*.class$ instead of just .class$ + return restartFilePattern.matcher(file.getName()).find(); + } else { + if (file.getName().toLowerCase().endsWith(".jar")) //$NON-NLS-1$ + return true; + return false; + } + } + + public void setRestartFilePattern(String filepattern) { + this.restartFilePattern = Pattern.compile(filepattern, Pattern.CASE_INSENSITIVE); } } Index: plugins/org.jboss.ide.eclipse.as.rse.core/src/org/jboss/ide/eclipse/as/rse/core/RSERemotePublishHandler.java =================================================================== --- plugins/org.jboss.ide.eclipse.as.rse.core/src/org/jboss/ide/eclipse/as/rse/core/RSERemotePublishHandler.java (revision 37255) +++ plugins/org.jboss.ide.eclipse.as.rse.core/src/org/jboss/ide/eclipse/as/rse/core/RSERemotePublishHandler.java (working copy) @@ -49,7 +49,7 @@ public IStatus[] copyFile(final IModuleFile mf, final IPath path, final IProgressMonitor monitor) throws CoreException { final File file = PublishUtil.getFile(mf); - shouldRestartModule |= method.getBehaviour().changedFileRequiresModuleRestart(file); + shouldRestartModule |= method.getBehaviour().changedFileRequiresModuleRestart(mf); final IPath remotePath = root.append(path); final CoreException[] coreEx = new CoreException[1]; Index: tests/org.jboss.ide.eclipse.as.test/src/org/jboss/ide/eclipse/as/test/publishing/v2/ModuleRestartDetectionTest.java =================================================================== --- tests/org.jboss.ide.eclipse.as.test/src/org/jboss/ide/eclipse/as/test/publishing/v2/ModuleRestartDetectionTest.java (revision 0) +++ tests/org.jboss.ide.eclipse.as.test/src/org/jboss/ide/eclipse/as/test/publishing/v2/ModuleRestartDetectionTest.java (revision 0) @@ -0,0 +1,138 @@ +/******************************************************************************* + * Copyright (c) 2011 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is made available under the terms of the + * Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package org.jboss.ide.eclipse.as.test.publishing.v2; + +import junit.framework.TestCase; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.wst.server.core.model.IModuleFile; +import org.jboss.ide.eclipse.as.core.server.internal.DeployableServerBehavior; +import org.jboss.ide.eclipse.as.test.publishing.v2.ModuleRestartDetectionTest.MockFile; + +public class ModuleRestartDetectionTest extends TestCase { + + static class MockFile implements IModuleFile { + + String name; + + public MockFile(String name) { + this.name = name; + } + + public IPath getModuleRelativePath() { + return null; + } + + public String getName() { + return name; + } + + public Object getAdapter(Class adapter) { + return null; + } + + public long getModificationStamp() { + return 0; + } + + } + + private DeployableServerBehavior behavior; + private MockFile mixedJar; + private MockFile classyjar; + private MockFile htmlfile; + private MockFile classfile; + private MockFile jarfile; + private MockFile nodotjar; + + public void testDefaults() { + + + assertTrue("Default behavior should restart on .jar", behavior.changedFileRequiresModuleRestart(jarfile)); + assertFalse("Default behavior should not restart on .class", behavior.changedFileRequiresModuleRestart(classfile)); + assertFalse("Default behavior should not restart on .html", behavior.changedFileRequiresModuleRestart(htmlfile)); + assertFalse("Default should not restart on file named classy.jarfile", behavior.changedFileRequiresModuleRestart(classyjar)); + assertFalse("Default should not restart on nodotjar", behavior.changedFileRequiresModuleRestart(nodotjar)); + + assertTrue("default behavior should restart on JAr too", behavior.changedFileRequiresModuleRestart(mixedJar)); + + } + + + public void setUp() { + behavior = new DeployableServerBehavior(); + + jarfile = new MockFile("blah.jar"); + classfile = new MockFile("blah.class"); + nodotjar = new MockFile("nodotjar"); + htmlfile = new MockFile("blah.html"); + classyjar = new MockFile("myclassy.jarfile"); + mixedJar = new MockFile("BLAH.JAr"); + } + + public void testClassEndOfLine() { + + String filepattern = ".class$"; + behavior.setRestartFilePattern(filepattern); + + assertFalse(filepattern + " should not restart on .jar", behavior.changedFileRequiresModuleRestart(jarfile)); + assertTrue(filepattern + " should restart on .class", behavior.changedFileRequiresModuleRestart(classfile)); + assertFalse(filepattern + " should not restart on .html", behavior.changedFileRequiresModuleRestart(htmlfile)); + assertFalse(filepattern + "Default should not restart on file named classy.jarfile", behavior.changedFileRequiresModuleRestart(classyjar)); + } + + public void testBasicOr() { + String filepattern = ".class|.jar"; + behavior.setRestartFilePattern(filepattern); + + assertTrue(filepattern + " should restart on .jar", behavior.changedFileRequiresModuleRestart(jarfile)); + assertTrue(filepattern + " should restart on .class", behavior.changedFileRequiresModuleRestart(classfile)); + assertFalse(filepattern + " should not restart on .html", behavior.changedFileRequiresModuleRestart(htmlfile)); + assertTrue(filepattern + " should restart on file named classy.jarfile", behavior.changedFileRequiresModuleRestart(classyjar)); + assertTrue(filepattern + " behavior should restart on JAr too", behavior.changedFileRequiresModuleRestart(mixedJar)); + } + + public void testCaseInsensitive() { + + assertTrue(behavior.changedFileRequiresModuleRestart(new MockFile(".jar"))); + + assertTrue(behavior.changedFileRequiresModuleRestart(new MockFile(".JAR"))); + + behavior.setRestartFilePattern(".jar"); + + assertTrue(behavior.changedFileRequiresModuleRestart(new MockFile(".jar"))); + + assertTrue(behavior.changedFileRequiresModuleRestart(new MockFile(".JAR"))); + + } + + public void testBasicOrEndOfLine() { + String filepattern = ".class$|.jar$"; + behavior.setRestartFilePattern(filepattern); + + assertTrue(filepattern + " should restart on .jar", behavior.changedFileRequiresModuleRestart(jarfile)); + assertTrue(filepattern + " should restart on .class", behavior.changedFileRequiresModuleRestart(classfile)); + assertFalse(filepattern + " should not restart on .html", behavior.changedFileRequiresModuleRestart(htmlfile)); + assertFalse(filepattern + "Default should not restart on file named classy.jarfile", behavior.changedFileRequiresModuleRestart(classyjar)); + + } + + public void testSystemProperty() { + + System.setProperty(DeployableServerBehavior.ORG_JBOSS_TOOLS_AS_RESTART_FILE_PATTERN,".blah"); + + behavior = new DeployableServerBehavior(); + + assertTrue(behavior.changedFileRequiresModuleRestart(new MockFile(".blah"))); + assertFalse(behavior.changedFileRequiresModuleRestart(new MockFile(".jar"))); + + } +}