Author: rmannibucau Date: Thu Jul 26 14:46:03 2012 New Revision: 1366024 URL: http://svn.apache.org/viewvc?rev=1366024&view=rev Log: TOMEE-344 synchronization between maven and deployed webapp, useful for some libraries able to hot reload classes or for resources
Added: openejb/trunk/openejb/maven/tomee-maven-plugin/src/main/java/org/apache/openejb/maven/plugin/Synchronization.java openejb/trunk/openejb/maven/tomee-maven-plugin/src/main/java/org/apache/openejb/maven/plugin/UpdatableTomEEMojo.java Modified: openejb/trunk/openejb/maven/tomee-maven-plugin/src/main/java/org/apache/openejb/maven/plugin/AbstractTomEEMojo.java openejb/trunk/openejb/maven/tomee-maven-plugin/src/main/java/org/apache/openejb/maven/plugin/RunTomEEMojo.java openejb/trunk/openejb/maven/tomee-maven-plugin/src/main/java/org/apache/openejb/maven/plugin/StartTomEEMojo.java Modified: openejb/trunk/openejb/maven/tomee-maven-plugin/src/main/java/org/apache/openejb/maven/plugin/AbstractTomEEMojo.java URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/maven/tomee-maven-plugin/src/main/java/org/apache/openejb/maven/plugin/AbstractTomEEMojo.java?rev=1366024&r1=1366023&r2=1366024&view=diff ============================================================================== --- openejb/trunk/openejb/maven/tomee-maven-plugin/src/main/java/org/apache/openejb/maven/plugin/AbstractTomEEMojo.java (original) +++ openejb/trunk/openejb/maven/tomee-maven-plugin/src/main/java/org/apache/openejb/maven/plugin/AbstractTomEEMojo.java Thu Jul 26 14:46:03 2012 @@ -544,11 +544,7 @@ public abstract class AbstractTomEEMojo final RemoteServer server = new RemoteServer(getConnectAttempts(), false); if (!getNoShutdownHook()) { - Runtime.getRuntime().addShutdownHook(new Thread() { - @Override public void run() { - server.stop(); - } - }); + addShutdownHooks(server); } getLog().info("Running '" + getClass().getSimpleName().replace("TomEEMojo", "").toLowerCase(Locale.ENGLISH) @@ -566,6 +562,14 @@ public abstract class AbstractTomEEMojo } } + protected void addShutdownHooks(final RemoteServer server) { + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override public void run() { + server.stop(); + } + }); + } + protected int getConnectAttempts() { return Integer.MAX_VALUE; } Modified: openejb/trunk/openejb/maven/tomee-maven-plugin/src/main/java/org/apache/openejb/maven/plugin/RunTomEEMojo.java URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/maven/tomee-maven-plugin/src/main/java/org/apache/openejb/maven/plugin/RunTomEEMojo.java?rev=1366024&r1=1366023&r2=1366024&view=diff ============================================================================== --- openejb/trunk/openejb/maven/tomee-maven-plugin/src/main/java/org/apache/openejb/maven/plugin/RunTomEEMojo.java (original) +++ openejb/trunk/openejb/maven/tomee-maven-plugin/src/main/java/org/apache/openejb/maven/plugin/RunTomEEMojo.java Thu Jul 26 14:46:03 2012 @@ -21,7 +21,7 @@ package org.apache.openejb.maven.plugin; * @goal run * @requiresDependencyResolution runtime */ -public class RunTomEEMojo extends AbstractTomEEMojo { +public class RunTomEEMojo extends UpdatableTomEEMojo { @Override public String getCmd() { return "start"; Modified: openejb/trunk/openejb/maven/tomee-maven-plugin/src/main/java/org/apache/openejb/maven/plugin/StartTomEEMojo.java URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/maven/tomee-maven-plugin/src/main/java/org/apache/openejb/maven/plugin/StartTomEEMojo.java?rev=1366024&r1=1366023&r2=1366024&view=diff ============================================================================== --- openejb/trunk/openejb/maven/tomee-maven-plugin/src/main/java/org/apache/openejb/maven/plugin/StartTomEEMojo.java (original) +++ openejb/trunk/openejb/maven/tomee-maven-plugin/src/main/java/org/apache/openejb/maven/plugin/StartTomEEMojo.java Thu Jul 26 14:46:03 2012 @@ -21,7 +21,7 @@ package org.apache.openejb.maven.plugin; * @goal start * @requiresDependencyResolution runtime */ -public class StartTomEEMojo extends AbstractTomEEMojo { +public class StartTomEEMojo extends UpdatableTomEEMojo { @Override public String getCmd() { return "start"; Added: openejb/trunk/openejb/maven/tomee-maven-plugin/src/main/java/org/apache/openejb/maven/plugin/Synchronization.java URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/maven/tomee-maven-plugin/src/main/java/org/apache/openejb/maven/plugin/Synchronization.java?rev=1366024&view=auto ============================================================================== --- openejb/trunk/openejb/maven/tomee-maven-plugin/src/main/java/org/apache/openejb/maven/plugin/Synchronization.java (added) +++ openejb/trunk/openejb/maven/tomee-maven-plugin/src/main/java/org/apache/openejb/maven/plugin/Synchronization.java Thu Jul 26 14:46:03 2012 @@ -0,0 +1,77 @@ +/* + * 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.apache.openejb.maven.plugin; + +import java.io.File; +import java.util.List; + +public class Synchronization { + private File resourcesDir; + private File binariesDir; + private File targetBinariesDir; + private File targetResourcesDir; + private int updateInterval; + private List<String> extensions; + + public File getResourcesDir() { + return resourcesDir; + } + + public void setResourcesDir(File resourcesDir) { + this.resourcesDir = resourcesDir; + } + + public File getBinariesDir() { + return binariesDir; + } + + public void setBinariesDir(File binariesDir) { + this.binariesDir = binariesDir; + } + + public File getTargetBinariesDir() { + return targetBinariesDir; + } + + public void setTargetBinariesDir(File targetBinariesDir) { + this.targetBinariesDir = targetBinariesDir; + } + + public File getTargetResourcesDir() { + return targetResourcesDir; + } + + public void setTargetResourcesDir(File targetResourcesDir) { + this.targetResourcesDir = targetResourcesDir; + } + + public int getUpdateInterval() { + return updateInterval; + } + + public void setUpdateInterval(int updateInterval) { + this.updateInterval = updateInterval; + } + + public List<String> getExtensions() { + return extensions; + } + + public void setExtensions(List<String> extensions) { + this.extensions = extensions; + } +} Added: openejb/trunk/openejb/maven/tomee-maven-plugin/src/main/java/org/apache/openejb/maven/plugin/UpdatableTomEEMojo.java URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/maven/tomee-maven-plugin/src/main/java/org/apache/openejb/maven/plugin/UpdatableTomEEMojo.java?rev=1366024&view=auto ============================================================================== --- openejb/trunk/openejb/maven/tomee-maven-plugin/src/main/java/org/apache/openejb/maven/plugin/UpdatableTomEEMojo.java (added) +++ openejb/trunk/openejb/maven/tomee-maven-plugin/src/main/java/org/apache/openejb/maven/plugin/UpdatableTomEEMojo.java Thu Jul 26 14:46:03 2012 @@ -0,0 +1,194 @@ +/* + * 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.apache.openejb.maven.plugin; + +import org.apache.openejb.config.RemoteServer; +import org.apache.openejb.loader.Files; +import org.codehaus.plexus.util.FileUtils; + +import java.io.File; +import java.io.FileFilter; +import java.io.IOException; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.TimeUnit; + +public abstract class UpdatableTomEEMojo extends AbstractTomEEMojo { + public static final int INITIAL_DELAY = 5000; + + /** + * @parameter + */ + private Synchronization synchronization; + + /** + * @parameter expression="${tomee-plugin.buildDir}" default-value="${project.build.directory}" + * @required + * @readOnly + */ + private File buildDir; + + /** + * @parameter expression="${tomee-plugin.baseDir}" default-value="${project.basedir}" + * @required + * @readOnly + */ + private File baseDir; + + /** + * @parameter expression="${tomee-plugin.finalName}" default-value="${project.build.finalName}" + * @required + */ + private String finalName; + + private Timer timer; + + @Override + protected void run() { + if (synchronization != null) { + if (synchronization.getBinariesDir() == null) { + synchronization.setBinariesDir(new File(buildDir, "classes")); + } + if (synchronization.getResourcesDir() == null) { + synchronization.setResourcesDir(new File(baseDir, "src/main/webapp")); + } + if (synchronization.getTargetResourcesDir() == null) { + synchronization.setTargetResourcesDir(new File(buildDir, "apache-tomee/webapps/" + finalName)); + } + if (synchronization.getTargetBinariesDir() == null) { + synchronization.setTargetBinariesDir(new File(buildDir, "apache-tomee/webapps/" + finalName + "/WEB-INF/classes")); + } + if (synchronization.getUpdateInterval() <= 0) { + synchronization.setUpdateInterval(15); // sec + } + if (synchronization.getExtensions() == null) { + synchronization.setExtensions(Arrays.asList(".html", ".css", ".js", ".xhtml")); + } + startSynchronizer(); + } + super.run(); + } + + @Override + protected void addShutdownHooks(final RemoteServer server) { + if (synchronization != null) { + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override public void run() { + timer.cancel(); + } + }); + } + super.addShutdownHooks(server); + } + + protected void startSynchronizer() { + timer = new Timer("tomee-maven-plugin-synchronizer"); + long interval = TimeUnit.SECONDS.toMillis(synchronization.getUpdateInterval()); + if (interval > INITIAL_DELAY) { + timer.scheduleAtFixedRate(new Synchronizer(), interval, interval); + } else { + timer.scheduleAtFixedRate(new Synchronizer(), INITIAL_DELAY, interval); + } + } + + private class Synchronizer extends TimerTask { + private final FileFilter fileFilter; + private long lastUpdate = System.currentTimeMillis(); + + private Synchronizer() { + fileFilter = new SuffixesFileFilter(synchronization.getExtensions()); + } + + @Override + public void run() { + final long ts = System.currentTimeMillis(); + updateFiles(synchronization.getResourcesDir(), synchronization.getTargetResourcesDir(), ts); + updateFiles(synchronization.getBinariesDir(), synchronization.getTargetBinariesDir(), ts); + lastUpdate = ts; + } + + private void updateFiles(final File source, final File output, final long ts) { + if (!source.isDirectory()) { + getLog().warn(source.getAbsolutePath() + " is not a directory, skipping"); + return; + } + + final Collection<File> files = Files.collect(source, fileFilter); + for (File file : files) { + if (file.isDirectory() + || file.lastModified() < lastUpdate) { + continue; + } + + updateFile(source, output, file, ts); + } + } + + private void updateFile(final File source, final File target, final File file, final long ts) { + String relativized = file.getAbsolutePath().replace(source.getAbsolutePath(), ""); + if (relativized.startsWith(File.separator)) { + relativized = relativized.substring(1); + } + + final File output = new File(target, relativized); + if (file.exists()) { + getLog().info("[Updating] " + file.getAbsolutePath() + " to " + output.getAbsolutePath()); + } else { + getLog().info("[Creating] " + file.getAbsolutePath() + " to " + output.getAbsolutePath()); + } + try { + if (!output.getParentFile().exists()) { + FileUtils.forceMkdir(output.getParentFile()); + } + FileUtils.copyFile(file, output); + output.setLastModified(ts); + } catch (IOException e) { + getLog().error(e); + } + } + } + + private static class SuffixesFileFilter implements FileFilter { + private final String[] suffixes; + + public SuffixesFileFilter(final List<String> extensions) { + if (extensions == null) { + suffixes = new String[0]; + } else { + suffixes = extensions.toArray(new String[extensions.size()]); + } + } + + @Override + public boolean accept(final File file) { + if (file.isDirectory()) { + return true; + } + + for (String suffix : suffixes) { + if (file.getName().endsWith(suffix)) { + return true; + } + } + + return false; + } + } +}