geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From djen...@apache.org
Subject svn commit: r407589 - in /geronimo/branches/1.1/modules/hot-deploy/src/java/org/apache/geronimo/deployment/hot: DirectoryHotDeployer.java DirectoryMonitor.java
Date Thu, 18 May 2006 16:44:21 GMT
Author: djencks
Date: Thu May 18 09:44:21 2006
New Revision: 407589

URL: http://svn.apache.org/viewvc?rev=407589&view=rev
Log:
GERONIMO-1443 backport from trunk make hot deployer accept plan-only deployments

Modified:
    geronimo/branches/1.1/modules/hot-deploy/src/java/org/apache/geronimo/deployment/hot/DirectoryHotDeployer.java
    geronimo/branches/1.1/modules/hot-deploy/src/java/org/apache/geronimo/deployment/hot/DirectoryMonitor.java

Modified: geronimo/branches/1.1/modules/hot-deploy/src/java/org/apache/geronimo/deployment/hot/DirectoryHotDeployer.java
URL: http://svn.apache.org/viewvc/geronimo/branches/1.1/modules/hot-deploy/src/java/org/apache/geronimo/deployment/hot/DirectoryHotDeployer.java?rev=407589&r1=407588&r2=407589&view=diff
==============================================================================
--- geronimo/branches/1.1/modules/hot-deploy/src/java/org/apache/geronimo/deployment/hot/DirectoryHotDeployer.java
(original)
+++ geronimo/branches/1.1/modules/hot-deploy/src/java/org/apache/geronimo/deployment/hot/DirectoryHotDeployer.java
Thu May 18 09:44:21 2006
@@ -37,6 +37,7 @@
 import javax.enterprise.deploy.spi.exceptions.DeploymentManagerCreationException;
 import javax.enterprise.deploy.spi.status.ProgressObject;
 import javax.enterprise.deploy.spi.factories.DeploymentFactory;
+
 import java.io.File;
 import java.util.Set;
 import java.util.Iterator;
@@ -49,10 +50,10 @@
 public class DirectoryHotDeployer implements HotDeployer, GBeanLifecycle { //todo: write
unit tests
     private static final Log log = LogFactory.getLog("org.apache.geronimo.deployment.hot.Hot
Deployer");
     // Try to make this stand out as the user is likely to get a ton of errors if this comes
up
-    private static final String BAD_LAYOUT_MESSAGE = "CANNOT DEPLOY: It looks like you unpacked
an application or module "+
-                   "directly into the hot deployment directory.  THIS DOES NOT WORK.  You
need to unpack into a "+
-                   "subdirectory directly under the hot deploy directory.  For example, if
the hot deploy directory "+
-                   "is 'deploy/' and your file is 'webapp.war' then you could unpack it into
a directory 'deploy/webapp.war/'";
+    private static final String BAD_LAYOUT_MESSAGE = "CANNOT DEPLOY: It looks like you unpacked
an application or module " +
+            "directly into the hot deployment directory.  THIS DOES NOT WORK.  You need to
unpack into a " +
+            "subdirectory directly under the hot deploy directory.  For example, if the hot
deploy directory " +
+            "is 'deploy/' and your file is 'webapp.war' then you could unpack it into a directory
'deploy/webapp.war/'";
     private DirectoryMonitor monitor;
     private String path;
     private ServerInfo serverInfo;
@@ -101,7 +102,7 @@
     }
 
     public void setDeploymentURI(String deploymentURI) {
-        if(deploymentURI != null && !deploymentURI.trim().equals("")) {
+        if (deploymentURI != null && !deploymentURI.trim().equals("")) {
             this.deploymentURI = deploymentURI.trim();
         }
     }
@@ -123,16 +124,16 @@
     }
 
     public void doStart() throws Exception {
-        if(factory == null) {
+        if (factory == null) {
             factory = new DeploymentFactoryImpl();
         }
         File dir = serverInfo.resolve(path);
-        if(!dir.exists()) {
-            if(!dir.mkdirs()) {
-                throw new IllegalStateException("Hot deploy directory "+dir.getAbsolutePath()+"
does not exist and cannot be created!");
+        if (!dir.exists()) {
+            if (!dir.mkdirs()) {
+                throw new IllegalStateException("Hot deploy directory " + dir.getAbsolutePath()
+ " does not exist and cannot be created!");
             }
-        } else if(!dir.canRead() || !dir.isDirectory()) {
-            throw new IllegalStateException("Hot deploy directory "+dir.getAbsolutePath()+"
is not a readable directory!");
+        } else if (!dir.canRead() || !dir.isDirectory()) {
+            throw new IllegalStateException("Hot deploy directory " + dir.getAbsolutePath()
+ " is not a readable directory!");
         }
         DeploymentManager mgr = null;
         try {
@@ -147,7 +148,7 @@
             t.setDaemon(true);
             t.start();
         } finally {
-            if(mgr != null) mgr.release();
+            if (mgr != null) mgr.release();
         }
     }
 
@@ -156,7 +157,7 @@
     }
 
     public void doFail() {
-        if(monitor != null) {
+        if (monitor != null) {
             monitor.close();
         }
     }
@@ -166,7 +167,7 @@
             DeployUtils.identifyTargetModuleIDs(startupModules, configId, true).toArray(new
TargetModuleID[0]);
             return true;
         } catch (DeploymentException e) {
-            log.debug("Found new file in deploy directory on startup with ID "+configId);
+            log.debug("Found new file in deploy directory on startup with ID " + configId);
             return false;
         }
     }
@@ -182,7 +183,7 @@
             AbstractName configListName = (AbstractName) i.next();
             try {
                 Boolean result = (Boolean) kernel.getAttribute(configListName, "kernelFullyStarted");
-                if(!result.booleanValue()) {
+                if (!result.booleanValue()) {
                     return false;
                 }
             } catch (Exception e) {
@@ -204,60 +205,67 @@
 
     public boolean validateFile(File file, String configId) {
         //todo: some more detailed evaluation
-        if(file.isDirectory() && (file.getName().equals("WEB-INF") || file.getName().equals("META-INF")))
{
-            log.error("("+file.getName()+") "+BAD_LAYOUT_MESSAGE);
+        if (file.isDirectory() && (file.getName().equals("WEB-INF") || file.getName().equals("META-INF")))
{
+            log.error("(" + file.getName() + ") " + BAD_LAYOUT_MESSAGE);
             return false;
         }
         return true;
     }
 
     public String fileAdded(File file) {
-        log.info("Deploying "+file.getName());
+        log.info("Deploying " + file.getName());
         DeploymentManager mgr = null;
         TargetModuleID[] modules = null;
         boolean completed = false;
         try {
             mgr = getDeploymentManager();
             Target[] targets = mgr.getTargets();
-            ProgressObject po = mgr.distribute(targets, file, null);
+            ProgressObject po;
+            if (DeployUtils.isJarFile(file) || file.isDirectory()) {
+                po = mgr.distribute(targets, file, null);
+            } else {
+                po = mgr.distribute(targets, null, file);
+            }
             waitForProgress(po);
-            if(po.getDeploymentStatus().isCompleted()) {
+            if (po.getDeploymentStatus().isCompleted()) {
                 modules = po.getResultTargetModuleIDs();
                 po = mgr.start(modules);
                 waitForProgress(po);
-                if(po.getDeploymentStatus().isCompleted()) {
+                if (po.getDeploymentStatus().isCompleted()) {
                     completed = true;
                 } else {
-                    log.warn("Unable to start some modules for "+file.getAbsolutePath());
+                    log.warn("Unable to start some modules for " + file.getAbsolutePath());
                 }
                 modules = po.getResultTargetModuleIDs();
                 for (int i = 0; i < modules.length; i++) {
                     TargetModuleID result = modules[i];
-                    System.out.print(DeployUtils.reformat("Deployed "+result.getModuleID()+(targets.length
> 1 ? " to "+result.getTarget().getName() : "")+(result.getWebURL() == null ? "" : " @
"+result.getWebURL()), 4, 72));
-                    if(result.getChildTargetModuleID() != null) {
+                    System.out.print(DeployUtils.reformat("Deployed " + result.getModuleID()
+ (targets.length > 1 ? " to " + result.getTarget().getName() : "") + (result.getWebURL()
== null ? "" : " @ " + result.getWebURL()), 4, 72));
+                    if (result.getChildTargetModuleID() != null) {
                         for (int j = 0; j < result.getChildTargetModuleID().length; j++)
{
                             TargetModuleID child = result.getChildTargetModuleID()[j];
-                            System.out.print(DeployUtils.reformat("  `-> "+child.getModuleID()+(child.getWebURL()
== null ? "" : " @ "+child.getWebURL()),4, 72));
+                            System.out.print(DeployUtils.reformat("  `-> " + child.getModuleID()
+ (child.getWebURL() == null ? "" : " @ " + child.getWebURL()), 4, 72));
                         }
                     }
                 }
             } else {
-                log.error("Unable to deploy: "+po.getDeploymentStatus().getMessage());
+                log.error("Unable to deploy: " + po.getDeploymentStatus().getMessage());
                 return null;
             }
         } catch (DeploymentManagerCreationException e) {
             log.error("Unable to open deployer", e);
             return null;
+        } catch (DeploymentException e) {
+            log.error("Unable to determine if file is a jar", e);
         } finally {
-            if(mgr != null) mgr.release();
+            if (mgr != null) mgr.release();
         }
-        if(completed && modules != null) {
-            if(modules.length == 1) {
+        if (completed && modules != null) {
+            if (modules.length == 1) {
                 return modules[0].getModuleID();
             } else {
                 return "";
             }
-        } else if(modules != null) { //distribute completed but not start or something like
that
+        } else if (modules != null) { //distribute completed but not start or something like
that
             return "";
         } else {
             return null;
@@ -266,14 +274,14 @@
 
     private DeploymentManager getDeploymentManager() throws DeploymentManagerCreationException
{
         DeploymentManager manager = factory.getDeploymentManager(deploymentURI, deploymentUser,
deploymentPassword);
-        if(manager instanceof JMXDeploymentManager) {
-            ((JMXDeploymentManager)manager).setLogConfiguration(false, true);
+        if (manager instanceof JMXDeploymentManager) {
+            ((JMXDeploymentManager) manager).setLogConfiguration(false, true);
         }
         return manager;
     }
 
     public boolean fileRemoved(File file, String configId) {
-        log.info("Undeploying "+file.getName());
+        log.info("Undeploying " + file.getName());
         DeploymentManager mgr = null;
         try {
             mgr = getDeploymentManager();
@@ -282,14 +290,14 @@
             ids = (TargetModuleID[]) DeployUtils.identifyTargetModuleIDs(ids, configId, true).toArray(new
TargetModuleID[0]);
             ProgressObject po = mgr.undeploy(ids);
             waitForProgress(po);
-            if(po.getDeploymentStatus().isCompleted()) {
+            if (po.getDeploymentStatus().isCompleted()) {
                 TargetModuleID[] modules = po.getResultTargetModuleIDs();
                 for (int i = 0; i < modules.length; i++) {
                     TargetModuleID result = modules[i];
-                    System.out.print(DeployUtils.reformat("Undeployed "+result.getModuleID()+(targets.length
> 1 ? " to "+result.getTarget().getName() : ""), 4, 72));
+                    System.out.print(DeployUtils.reformat("Undeployed " + result.getModuleID()
+ (targets.length > 1 ? " to " + result.getTarget().getName() : ""), 4, 72));
                 }
             } else {
-                log.error("Unable to undeploy "+file.getAbsolutePath()+"("+configId+")"+po.getDeploymentStatus().getMessage());
+                log.error("Unable to undeploy " + file.getAbsolutePath() + "(" + configId
+ ")" + po.getDeploymentStatus().getMessage());
                 return false;
             }
         } catch (DeploymentManagerCreationException e) {
@@ -299,47 +307,52 @@
             log.error("Unable to undeploy", e);
             return false;
         } finally {
-            if(mgr != null) mgr.release();
+            if (mgr != null) mgr.release();
         }
         return true;
     }
 
     public void fileUpdated(File file, String configId) {
-        log.info("Redeploying "+file.getName());
+        log.info("Redeploying " + file.getName());
         DeploymentManager mgr = null;
         try {
             mgr = getDeploymentManager();
             Target[] targets = mgr.getTargets();
             TargetModuleID[] ids = mgr.getAvailableModules(null, targets);
             ids = (TargetModuleID[]) DeployUtils.identifyTargetModuleIDs(ids, configId, true).toArray(new
TargetModuleID[0]);
-            ProgressObject po = mgr.redeploy(ids, file, null);
+            ProgressObject po;
+            if (DeployUtils.isJarFile(file) || file.isDirectory()) {
+                po = mgr.redeploy(ids, file, null);
+            } else {
+                po = mgr.redeploy(ids, null, file);
+            }
             waitForProgress(po);
-            if(po.getDeploymentStatus().isCompleted()) {
+            if (po.getDeploymentStatus().isCompleted()) {
                 TargetModuleID[] modules = po.getResultTargetModuleIDs();
                 for (int i = 0; i < modules.length; i++) {
                     TargetModuleID result = modules[i];
-                    System.out.print(DeployUtils.reformat("Redeployed "+result.getModuleID()+(targets.length
> 1 ? " to "+result.getTarget().getName() : "")+(result.getWebURL() == null ? "" : " @
"+result.getWebURL()), 4, 72));
-                    if(result.getChildTargetModuleID() != null) {
+                    System.out.print(DeployUtils.reformat("Redeployed " + result.getModuleID()
+ (targets.length > 1 ? " to " + result.getTarget().getName() : "") + (result.getWebURL()
== null ? "" : " @ " + result.getWebURL()), 4, 72));
+                    if (result.getChildTargetModuleID() != null) {
                         for (int j = 0; j < result.getChildTargetModuleID().length; j++)
{
                             TargetModuleID child = result.getChildTargetModuleID()[j];
-                            System.out.print(DeployUtils.reformat("  `-> "+child.getModuleID()+(child.getWebURL()
== null ? "" : " @ "+child.getWebURL()),4, 72));
+                            System.out.print(DeployUtils.reformat("  `-> " + child.getModuleID()
+ (child.getWebURL() == null ? "" : " @ " + child.getWebURL()), 4, 72));
                         }
                     }
                 }
             } else {
-                log.error("Unable to undeploy "+file.getAbsolutePath()+"("+configId+")"+po.getDeploymentStatus().getMessage());
+                log.error("Unable to undeploy " + file.getAbsolutePath() + "(" + configId
+ ")" + po.getDeploymentStatus().getMessage());
             }
         } catch (DeploymentManagerCreationException e) {
             log.error("Unable to open deployer", e);
         } catch (Exception e) {
             log.error("Unable to undeploy", e);
         } finally {
-            if(mgr != null) mgr.release();
+            if (mgr != null) mgr.release();
         }
     }
 
     private void waitForProgress(ProgressObject po) {
-        while(po.getDeploymentStatus().isRunning()) {
+        while (po.getDeploymentStatus().isRunning()) {
             try {
                 Thread.sleep(100);
             } catch (InterruptedException e) {

Modified: geronimo/branches/1.1/modules/hot-deploy/src/java/org/apache/geronimo/deployment/hot/DirectoryMonitor.java
URL: http://svn.apache.org/viewvc/geronimo/branches/1.1/modules/hot-deploy/src/java/org/apache/geronimo/deployment/hot/DirectoryMonitor.java?rev=407589&r1=407588&r2=407589&view=diff
==============================================================================
--- geronimo/branches/1.1/modules/hot-deploy/src/java/org/apache/geronimo/deployment/hot/DirectoryMonitor.java
(original)
+++ geronimo/branches/1.1/modules/hot-deploy/src/java/org/apache/geronimo/deployment/hot/DirectoryMonitor.java
Thu May 18 09:44:21 2006
@@ -19,8 +19,10 @@
 import org.apache.commons.logging.LogFactory;
 import org.apache.commons.logging.Log;
 import org.apache.geronimo.deployment.cli.DeployUtils;
+
 import java.io.File;
 import java.io.Serializable;
+import java.io.IOException;
 import java.util.Map;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -40,6 +42,7 @@
  */
 public class DirectoryMonitor implements Runnable {
     private static final Log log = LogFactory.getLog(DirectoryMonitor.class);
+
     public static interface Listener {
         /**
          * The directory monitor doesn't take any action unless this method
@@ -47,6 +50,7 @@
          * running, etc.).
          */
         boolean isServerRunning();
+
         /**
          * Called during initialization on all files in the hot deploy
          * directory.
@@ -137,8 +141,8 @@
      * added, next time the thread awakens.
      */
     public void setDirectory(File directory) {
-        if(!directory.isDirectory() || !directory.canRead()) {
-            throw new IllegalArgumentException("Cannot monitor directory "+directory.getAbsolutePath());
+        if (!directory.isDirectory() || !directory.canRead()) {
+            throw new IllegalArgumentException("Cannot monitor directory " + directory.getAbsolutePath());
         }
         this.directory = directory;
     }
@@ -153,18 +157,18 @@
 
     public void run() {
         boolean serverStarted = false, initialized = false;
-        while(!done) {
+        while (!done) {
             try {
                 Thread.sleep(pollIntervalMillis);
             } catch (InterruptedException e) {
                 continue;
             }
-            if(listener != null) {
-                if(!serverStarted && listener.isServerRunning()) {
+            if (listener != null) {
+                if (!serverStarted && listener.isServerRunning()) {
                     serverStarted = true;
                 }
-                if(serverStarted) {
-                    if(!initialized) {
+                if (serverStarted) {
+                    if (!initialized) {
                         initialized = true;
                         initialize();
                         listener.started();
@@ -181,21 +185,21 @@
         File[] children = parent.listFiles();
         for (int i = 0; i < children.length; i++) {
             File child = children[i];
-            if(!child.canRead()) {
+            if (!child.canRead()) {
                 continue;
             }
             FileInfo now = child.isDirectory() ? getDirectoryInfo(child) : getFileInfo(child);
             now.setChanging(false);
             try {
                 now.setConfigId(calculateModuleId(child));
-                if(listener == null || listener.isFileDeployed(child, now.getConfigId()))
{
-                    if(listener != null) {
+                if (listener == null || listener.isFileDeployed(child, now.getConfigId()))
{
+                    if (listener != null) {
                         now.setModified(listener.getDeploymentTime(child, now.getConfigId()));
                     }
                     files.put(now.getPath(), now);
                 }
             } catch (Exception e) {
-                log.error("Unable to scan file "+child.getAbsolutePath()+" during initialization",
e);
+                log.error("Unable to scan file " + child.getAbsolutePath() + " during initialization",
e);
             }
         }
     }
@@ -206,7 +210,7 @@
     private void scanDirectory() {
         File parent = directory;
         File[] children = parent.listFiles();
-        if(!directory.exists() || children == null) {
+        if (!directory.exists() || children == null) {
             log.error("Hot deploy directory has disappeared!  Shutting down directory monitor.");
             done = true;
             return;
@@ -215,22 +219,22 @@
         List actions = new LinkedList();
         for (int i = 0; i < children.length; i++) {
             File child = children[i];
-            if(!child.canRead()) {
+            if (!child.canRead()) {
                 continue;
             }
             FileInfo now = child.isDirectory() ? getDirectoryInfo(child) : getFileInfo(child);
             FileInfo then = (FileInfo) files.get(now.getPath());
-            if(then == null) { // Brand new, wait a bit to make sure it's not still changing
+            if (then == null) { // Brand new, wait a bit to make sure it's not still changing
                 now.setNewFile(true);
                 files.put(now.getPath(), now);
-                log.debug("New File: "+now.getPath());
+                log.debug("New File: " + now.getPath());
             } else {
                 oldList.remove(then.getPath());
-                if(now.isSame(then)) { // File is the same as the last time we scanned it
-                    if(then.isChanging()) {
-                        log.debug("File finished changing: "+now.getPath());
+                if (now.isSame(then)) { // File is the same as the last time we scanned it
+                    if (then.isChanging()) {
+                        log.debug("File finished changing: " + now.getPath());
                         // Used to be changing, now in (hopefully) its final state
-                        if(then.isNewFile()) {
+                        if (then.isNewFile()) {
                             actions.add(new FileAction(FileAction.NEW_FILE, child, then));
                         } else {
                             actions.add(new FileAction(FileAction.UPDATED_FILE, child, then));
@@ -243,7 +247,7 @@
                     now.setConfigId(then.getConfigId());
                     now.setNewFile(then.isNewFile());
                     files.put(now.getPath(), now);
-                    log.debug("File Changed: "+now.getPath());
+                    log.debug("File Changed: " + now.getPath());
                 }
             }
         }
@@ -251,18 +255,18 @@
         for (Iterator it = oldList.iterator(); it.hasNext();) {
             String name = (String) it.next();
             FileInfo info = (FileInfo) files.get(name);
-            log.debug("File removed: "+name);
-            if(info.isNewFile()) { // Was never added, just whack it
+            log.debug("File removed: " + name);
+            if (info.isNewFile()) { // Was never added, just whack it
                 files.remove(name);
             } else {
                 actions.add(new FileAction(FileAction.REMOVED_FILE, new File(name), info));
             }
         }
-        if(listener != null) {
+        if (listener != null) {
             // First pass: validate all changed files, so any obvious errors come out first
             for (Iterator it = actions.iterator(); it.hasNext();) {
                 FileAction action = (FileAction) it.next();
-                if(!listener.validateFile(action.child, action.info.getConfigId())) {
+                if (!listener.validateFile(action.child, action.info.getConfigId())) {
                     resolveFile(action);
                     it.remove();
                 }
@@ -271,25 +275,25 @@
             for (Iterator it = actions.iterator(); it.hasNext();) {
                 FileAction action = (FileAction) it.next();
                 try {
-                    if(action.action == FileAction.REMOVED_FILE) {
-                        if(listener.fileRemoved(action.child, action.info.getConfigId()))
{
+                    if (action.action == FileAction.REMOVED_FILE) {
+                        if (listener.fileRemoved(action.child, action.info.getConfigId()))
{
                             files.remove(action.child.getPath());
                         }
-                    } else if(action.action == FileAction.NEW_FILE) {
+                    } else if (action.action == FileAction.NEW_FILE) {
                         String result = listener.fileAdded(action.child);
-                        if(result != null) {
-                            if(!result.equals("")) {
+                        if (result != null) {
+                            if (!result.equals("")) {
                                 action.info.setConfigId(result);
                             } else {
                                 action.info.setConfigId(calculateModuleId(action.child));
                             }
                             action.info.setNewFile(false);
                         }
-                    } else if(action.action == FileAction.UPDATED_FILE) {
+                    } else if (action.action == FileAction.UPDATED_FILE) {
                         listener.fileUpdated(action.child, action.info.getConfigId());
                     }
                 } catch (Exception e) {
-                    log.error("Unable to "+action.getActionName()+" file "+action.child.getAbsolutePath(),
e);
+                    log.error("Unable to " + action.getActionName() + " file " + action.child.getAbsolutePath(),
e);
                 } finally {
                     resolveFile(action);
                 }
@@ -298,7 +302,7 @@
     }
 
     private void resolveFile(FileAction action) {
-        if(action.action == FileAction.REMOVED_FILE) {
+        if (action.action == FileAction.REMOVED_FILE) {
             files.remove(action.child.getPath());
         } else {
             action.info.setChanging(false);
@@ -310,9 +314,13 @@
         try {
             moduleId = DeployUtils.extractModuleIdFromArchive(module);
         } catch (Exception e) {
-            log.warn("Unable to calculate module ID for module "+module.getAbsolutePath()+"
["+e.getMessage()+"]");
+            try {
+                moduleId = DeployUtils.extractModuleIdFromPlan(module);
+            } catch (IOException e2) {
+                log.warn("Unable to calculate module ID for file " + module.getAbsolutePath()
+ " [" + e2.getMessage() + "]");
+            }
         }
-        if(moduleId == null) {
+        if (moduleId == null) {
             int pos = module.getName().lastIndexOf('.');
             moduleId = pos > -1 ? module.getName().substring(0, pos) : module.getName();
         }
@@ -337,15 +345,15 @@
         long test;
         for (int i = 0; i < children.length; i++) {
             File child = children[i];
-            if(!child.canRead()) {
+            if (!child.canRead()) {
                 continue;
             }
-            if(child.isDirectory()) {
+            if (child.isDirectory()) {
                 test = getLastModifiedInDir(child);
             } else {
                 test = child.lastModified();
             }
-            if(test > value) {
+            if (test > value) {
                 value = test;
             }
         }
@@ -437,7 +445,7 @@
         }
 
         public boolean isSame(FileInfo info) {
-            if(!path.equals(info.path)) {
+            if (!path.equals(info.path)) {
                 throw new IllegalArgumentException("Should only be used to compare two files
representing the same path!");
             }
             return size == info.size && modified == info.modified;



Mime
View raw message