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;
+        }
+    }
+}


Reply via email to