Author: paperwing
Date: 2012-07-24 16:20:54 -0700 (Tue, 24 Jul 2012)
New Revision: 29978

Modified:
   
core3/impl/trunk/app-impl/src/main/java/org/cytoscape/app/internal/CyActivator.java
   
core3/impl/trunk/app-impl/src/main/java/org/cytoscape/app/internal/manager/App.java
   
core3/impl/trunk/app-impl/src/main/java/org/cytoscape/app/internal/manager/AppManager.java
   
core3/impl/trunk/app-impl/src/main/java/org/cytoscape/app/internal/manager/AppParser.java
   
core3/impl/trunk/app-impl/src/main/java/org/cytoscape/app/internal/manager/KarafArchiveApp.java
   
core3/impl/trunk/app-impl/src/main/java/org/cytoscape/app/internal/manager/SimpleApp.java
Log:
App manager now uses FileAlterationObservers to perform app install, uninstall, 
and disabling. This makes it easier to support the user moving the app file 
between the installed, uninstalled, and disabled apps directories without 
problems such as receiving a file-create and a file-delete event in unspecified 
order from the Apache FileAlterationMonitor when files are moved, which makes 
it difficult to track app file movement. Also, now no longer needs 
implementation to respond to app file movement as installation is now done 
internally by app file movement to trigger work done by the 
FileAlterationObservers.

Modified: 
core3/impl/trunk/app-impl/src/main/java/org/cytoscape/app/internal/CyActivator.java
===================================================================
--- 
core3/impl/trunk/app-impl/src/main/java/org/cytoscape/app/internal/CyActivator.java
 2012-07-24 21:17:27 UTC (rev 29977)
+++ 
core3/impl/trunk/app-impl/src/main/java/org/cytoscape/app/internal/CyActivator.java
 2012-07-24 23:20:54 UTC (rev 29978)
@@ -120,6 +120,7 @@
 import org.cytoscape.task.write.ExportVizmapTaskFactory;
 import org.cytoscape.task.write.SaveSessionAsTaskFactory;
 
+import java.util.Map.Entry;
 import java.util.Properties;
 import java.util.concurrent.Executors;
 
@@ -349,6 +350,12 @@
                
                FeaturesService featuresService = getService(bc, 
FeaturesService.class);
                
+               Properties properties = System.getProperties();
+
+               for (Entry<Object, Object> entry : properties.entrySet()) {
+                       //System.out.println("Entry: " + entry.getKey() + ", 
value: " + entry.getValue());
+               }
+               
                // Instantiate new manager
                final AppManager appManager = new AppManager(cyAppAdapter, 
                                cyApplicationConfigurationServiceRef, 
webQuerier, featuresService);

Modified: 
core3/impl/trunk/app-impl/src/main/java/org/cytoscape/app/internal/manager/App.java
===================================================================
--- 
core3/impl/trunk/app-impl/src/main/java/org/cytoscape/app/internal/manager/App.java
 2012-07-24 21:17:27 UTC (rev 29977)
+++ 
core3/impl/trunk/app-impl/src/main/java/org/cytoscape/app/internal/manager/App.java
 2012-07-24 23:20:54 UTC (rev 29978)
@@ -12,6 +12,7 @@
 import org.apache.commons.io.FileUtils;
 import org.cytoscape.app.AbstractCyApp;
 import org.cytoscape.app.CyAppAdapter;
+import org.cytoscape.app.internal.exception.AppDisableException;
 import org.cytoscape.app.internal.exception.AppInstallException;
 import org.cytoscape.app.internal.exception.AppInstanceException;
 import org.cytoscape.app.internal.exception.AppUninstallException;
@@ -78,9 +79,10 @@
         */
        public enum AppStatus{
                INSTALLED("Installed"),
-               TO_BE_UNINSTALLED("Will be uninstalled after restart"),
-               TO_BE_DISABLED("Will be disabled after restart"),
-               DISABLED("Disabled");
+               TO_BE_UNINSTALLED("Uninstalled-on-restart"),
+               TO_BE_DISABLED("Disable-on-restart"),
+               DISABLED("Disabled"),
+               UNINSTALLED("Uninstalled");
                
                String readableStatus;
                
@@ -138,6 +140,8 @@
         */
        public abstract void uninstall(AppManager appManager) throws 
AppUninstallException;
        
+       public abstract void disable(AppManager appManager) throws 
AppDisableException;
+       
        /**
         * Default app installation method that can be used by classes 
extending this class.
         * 
@@ -340,7 +344,7 @@
         * @return A new name of the file that does not collide with any 
non-directory file in the given
         * paths. If the given filename had no collisions, then an identical 
filename is returned.
         */
-       private String suggestFileName(Collection<String> directoryPaths, 
String desiredFileName) {
+       protected String suggestFileName(Collection<String> directoryPaths, 
String desiredFileName) {
                
                int postfixNumber = 1;
                boolean nameCollision = false;
@@ -632,4 +636,61 @@
         return ret;  
     }
 
+       /**
+        * Moves an app file to the given directory, copying the app if it is 
outside one of the local app storage directories
+        * and moving if it is not. Also assigns filename that does not 
colliide with any from the local app storage directories.
+        * 
+        * @param appManager A reference to the app manager
+        * @param targetDirectory The local storage directory to move to, such 
as the local sotrage directory
+        * containing installed apps obtained via the app manager
+        * @throws IOException If there was an error while moving/copying the 
file
+        */
+       public void moveAppFile(AppManager appManager, File targetDirectory) 
throws IOException {
+               File parentPath = this.getAppFile().getParentFile();
+               File installDirectoryPath = new 
File(appManager.getKarafDeployDirectory());
+               File disabledDirectoryPath = new 
File(appManager.getDisabledAppsPath());
+               File uninstallDirectoryPath = new 
File(appManager.getUninstalledAppsPath());
+
+               // Want to make sure the app file's name does not collide with 
another name in these directories
+               LinkedList<String> uniqueNameDirectories = new 
LinkedList<String>();
+               
+               if (!parentPath.equals(installDirectoryPath))
+                       
uniqueNameDirectories.add(installDirectoryPath.getAbsolutePath());
+               
+               if (!parentPath.equals(disabledDirectoryPath))  
+                       
uniqueNameDirectories.add(disabledDirectoryPath.getAbsolutePath());
+       
+               if (!parentPath.equals(uninstallDirectoryPath)) 
+                       
uniqueNameDirectories.add(uninstallDirectoryPath.getAbsolutePath());
+               
+               // If the app file is in one of these directories, do a move 
instead of a copy
+               LinkedList<File> moveDirectories = new LinkedList<File>();
+               moveDirectories.add(installDirectoryPath);
+               moveDirectories.add(disabledDirectoryPath);
+               moveDirectories.add(uninstallDirectoryPath);
+               
+               File targetFile = new File(targetDirectory.getAbsolutePath() + 
File.separator 
+                               + suggestFileName(uniqueNameDirectories, 
this.getAppFile().getName()));
+               
+               if (!targetDirectory.equals(parentPath)) {
+                       if (moveDirectories.contains(parentPath)) {
+                               FileUtils.moveFile(this.getAppFile(), 
targetFile);
+                               this.setAppFile(targetFile);
+                       } else {
+                               FileUtils.copyFile(this.getAppFile(), 
targetFile);
+                               this.setAppFile(targetFile);
+                       }
+               }
+       }
+       
+       protected boolean checkAppAlreadyInstalled(AppManager appManager) {
+               boolean appAlreadyInstalled = false;
+               for (App app : appManager.getApps()) {
+                       if (app.heuristicEquals(this)) {
+                               appAlreadyInstalled = true;
+                       }
+               }
+               
+               return appAlreadyInstalled;
+       }
 }

Modified: 
core3/impl/trunk/app-impl/src/main/java/org/cytoscape/app/internal/manager/AppManager.java
===================================================================
--- 
core3/impl/trunk/app-impl/src/main/java/org/cytoscape/app/internal/manager/AppManager.java
  2012-07-24 21:17:27 UTC (rev 29977)
+++ 
core3/impl/trunk/app-impl/src/main/java/org/cytoscape/app/internal/manager/AppManager.java
  2012-07-24 23:20:54 UTC (rev 29978)
@@ -4,28 +4,21 @@
 import java.io.FileFilter;
 import java.io.IOException;
 import java.util.Collection;
-import java.util.Date;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Set;
-import java.util.concurrent.Executors;
 import java.util.jar.JarFile;
 import java.util.jar.Manifest;
 import java.util.zip.ZipException;
-import java.util.zip.ZipFile;
-
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOCase;
-import org.apache.commons.io.monitor.FileAlterationListener;
 import org.apache.commons.io.monitor.FileAlterationListenerAdaptor;
 import org.apache.commons.io.monitor.FileAlterationMonitor;
 import org.apache.commons.io.monitor.FileAlterationObserver;
-import org.apache.karaf.features.Feature;
 import org.apache.karaf.features.FeaturesService;
 import org.cytoscape.app.AbstractCyApp;
-import org.cytoscape.app.CyAppAdapter;
 import org.cytoscape.app.internal.event.AppsChangedEvent;
 import org.cytoscape.app.internal.event.AppsChangedListener;
+import org.cytoscape.app.internal.exception.AppDisableException;
 import org.cytoscape.app.internal.exception.AppInstallException;
 import org.cytoscape.app.internal.exception.AppParsingException;
 import org.cytoscape.app.internal.exception.AppUninstallException;
@@ -33,7 +26,6 @@
 import org.cytoscape.app.internal.net.WebQuerier;
 import org.cytoscape.application.CyApplicationConfiguration;
 
-import org.cytoscape.app.internal.net.server.LocalHttpServer;
 import org.cytoscape.app.internal.util.DebugHelper;
 import org.cytoscape.app.swing.CySwingAppAdapter;
 import org.slf4j.Logger;
@@ -68,7 +60,7 @@
        
        /** This subdirectory in the local Cytoscape storage directory is used 
to store app data, as 
         * well as installed and uninstalled apps. */
-       private static final String APPS_DIRECTORY_NAME = "3.0/apps";
+       private static final String APPS_DIRECTORY_NAME = "3.0" + 
File.separator + "apps";
        
        /** The set of all apps, represented by {@link App} objects, registered 
to this App Manager. */
        private Set<App> apps;
@@ -148,12 +140,13 @@
                this.appListeners = new HashSet<AppsChangedListener>();
 
                // Install previously enabled apps
-               installAppsInDirectory(new File(getKarafDeployDirectory()), 
false);
-               installAppsInDirectory(new File(getInstalledAppsPath()), true);
                
+               //installAppsInDirectory(new File(getKarafDeployDirectory()), 
false);
+               //installAppsInDirectory(new File(getInstalledAppsPath()), 
true);
+               
                // Load apps from the "uninstalled apps" directory
-               Set<App> uninstalledApps = obtainAppsFromDirectory(new 
File(getUninstalledAppsPath()), true);
-               apps.addAll(uninstalledApps);
+               //Set<App> uninstalledApps = obtainAppsFromDirectory(new 
File(getUninstalledAppsPath()), true);
+               //apps.addAll(uninstalledApps);
                
                DebugHelper.print(this, "config dir: " + 
applicationConfiguration.getConfigurationDirectoryLocation());
        }
@@ -169,71 +162,142 @@
        private void setupAlterationMonitor() {
                // Set up the FileAlterationMonitor to install/uninstall apps 
when apps are moved in/out of the 
                // installed/uninstalled app directories
-               fileAlterationMonitor = new FileAlterationMonitor(30000L);
+               fileAlterationMonitor = new FileAlterationMonitor(2000L);
                
                File installedAppsPath = new File(getInstalledAppsPath());
                
                FileAlterationObserver installAlterationObserver = new 
FileAlterationObserver(
                                installedAppsPath, new 
SingleLevelFileFilter(installedAppsPath), IOCase.SYSTEM);
                
+               final AppManager appManager = this;
+               
                // Listen for events on the "installed apps" folder
                installAlterationObserver.addListener(new 
FileAlterationListenerAdaptor() {
                        @Override
-                       public void onFileDelete(File file) {
-                               DebugHelper.print("Install directory file 
deleted");
+                       public void onFileCreate(File file) {
+                               DebugHelper.print("Install directory file 
created");
                                
+                               App parsedApp = null;
                                try {
-                                       String canonicalPath = 
file.getCanonicalPath();
-                                       
-                                       for (App app : apps) {
-                                               File appFile = app.getAppFile();
+                                       parsedApp = appParser.parseApp(file);
+                               } catch (AppParsingException e) {
+                                       return;
+                               }
+                               
+                               App registeredApp = null;
+                               for (App app : apps) {
+                                       if (parsedApp.heuristicEquals(app)) {
+                                               registeredApp = app;
                                                
-                                               if (appFile != null 
-                                                               && 
appFile.getCanonicalPath().equals(canonicalPath)) {
-
-                                                       app.setAppFile(new 
File(getUninstalledAppsPath() + File.separator + appFile.getName()));
-                                                       
-                                                       try {
-                                                               
uninstallApp(app);
-                                                       } catch 
(AppUninstallException e) {
-                                                               
logger.warn("Failed to uninstall app " + app.getAppName() + " when it was 
removed from the local install directory.");
-                                                       }
-                                               }
+                                               // Update file reference to 
reflect file having been moved
+                                               registeredApp.setAppFile(file);
                                        }
-                               } catch (IOException e) {
+                               }
+                               
+                               try {
+                                       if (registeredApp == null) {
+                                               apps.add(parsedApp);
+                                               parsedApp.install(appManager);
+                                       } else {
+                                               
registeredApp.install(appManager);
+                                       }
                                        
-                                       e.printStackTrace();
+                                       fireAppsChangedEvent();
+                               } catch (AppInstallException e) {
                                }
                        }
-                       
+               });
+               
+               FileAlterationObserver disableAlterationObserver = new 
FileAlterationObserver(
+                               getDisabledAppsPath(), new 
SingleLevelFileFilter(new File(getDisabledAppsPath())), IOCase.SYSTEM);
+               
+               // Listen for events on the "disabled apps" folder
+               disableAlterationObserver.addListener(new 
FileAlterationListenerAdaptor() {
                        @Override
                        public void onFileCreate(File file) {
-                               DebugHelper.print("Install directory file 
created");
-                               
                                App parsedApp = null;
                                try {
                                        parsedApp = appParser.parseApp(file);
-                                       installApp(parsedApp);
-
-                                       DebugHelper.print("Installed: " + 
parsedApp.getAppName());
                                } catch (AppParsingException e) {
-                                       DebugHelper.print("Failed to parse: " + 
file.getName());
-                               } catch (AppInstallException e) {
-                                       DebugHelper.print("Failed to install: " 
+ parsedApp.getAppName());
+                                       return;
                                }
-                       
+                               
+                               App registeredApp = null;
+                               for (App app : apps) {
+                                       if (parsedApp.heuristicEquals(app)) {
+                                               registeredApp = app;
+                                               
+                                               // Update file reference to 
reflect file having been moved
+                                               registeredApp.setAppFile(file);
+                                       }
+                               }
+                               
+                               try {
+                                       if (registeredApp == null) {
+                                               apps.add(parsedApp);
+                                               parsedApp.disable(appManager);
+                                       } else {
+                                               
registeredApp.disable(appManager);
+                                       }
+                                       
+                                       fireAppsChangedEvent();
+                               } catch (AppDisableException e) {
+                               }
                        }
-                       
+               });
+               
+               
+               FileAlterationObserver uninstallAlterationObserver = new 
FileAlterationObserver(
+                               getUninstalledAppsPath(), new 
SingleLevelFileFilter(new File(getUninstalledAppsPath())), IOCase.SYSTEM);
+               
+               // Listen for events on the "disabled apps" folder
+               uninstallAlterationObserver.addListener(new 
FileAlterationListenerAdaptor() {
                        @Override
-                       public void onFileChange(File file) {
+                       public void onFileCreate(File file) {
+                               App parsedApp = null;
+                               try {
+                                       parsedApp = appParser.parseApp(file);
+                               } catch (AppParsingException e) {
+                                       return;
+                               }
+                               
+                               App registeredApp = null;
+                               for (App app : apps) {
+                                       if (parsedApp.heuristicEquals(app)) {
+                                               registeredApp = app;
+                                               
+                                               // Update file reference to 
reflect file having been moved
+                                               registeredApp.setAppFile(file);
+                                       }
+                               }
+                               
+                               try {
+                                       if (registeredApp == null) {
+                                               apps.add(parsedApp);
+                                               parsedApp.uninstall(appManager);
+                                       } else {
+                                               
registeredApp.uninstall(appManager);
+                                       }
+                                       
+                                       fireAppsChangedEvent();
+                               } catch (AppUninstallException e) {
+                               }
                        }
                });
                
-               setupKarafDeployMonitor(fileAlterationMonitor);
                
+               // setupKarafDeployMonitor(fileAlterationMonitor);
+               
                try {
-                       //installAlterationObserver.initialize();
-                       
//fileAlterationMonitor.addObserver(installAlterationObserver);
+                       installAlterationObserver.initialize();
+                       
fileAlterationMonitor.addObserver(installAlterationObserver);
+                       
+                       disableAlterationObserver.initialize();
+                       
fileAlterationMonitor.addObserver(disableAlterationObserver);
+                       
+                       uninstallAlterationObserver.initialize();
+                       
fileAlterationMonitor.addObserver(uninstallAlterationObserver);
+                       
                        fileAlterationMonitor.start();
                } catch (Exception e) {
                        // TODO Auto-generated catch block
@@ -275,7 +339,7 @@
                                        try {
                                                parsedApp = 
appParser.parseApp(file);
                                                
-                                               if (parsedApp instanceof 
SimpleApp) {
+                                               if (parsedApp instanceof 
SimpleAppOld) {
                                                        logger.warn("A simple 
app " + file.getName() + " was moved to the " 
                                                                        + 
"framework/deploy directory. It should be installed via the "
                                                                        + "app 
manager. Installing anyway..");
@@ -358,26 +422,10 @@
        public void installApp(App app) throws AppInstallException {
                
                try {
-                       app.install(this);
-               } catch (AppInstallException e) {
-                       if (app.getAppFile() != null) {
-                               app.getAppFile().delete();
-                       }
-                       
-                       throw new AppInstallException(e.getMessage());
+                       app.moveAppFile(this, new File(getInstalledAppsPath()));
+               } catch (IOException e) {
+                       throw new AppInstallException("Unable to move app file, 
" + e.getMessage());
                }
-               
-               // For bundle apps, remove temporary files from Karaf deploy 
directory on exit
-               if (app instanceof KarafArchiveApp) {
-                       File temporaryInstallFile = ((KarafArchiveApp) 
app).getAppTemporaryInstallFile();
-                       
-                       if (temporaryInstallFile != null) {
-                               // temporaryInstallFile.deleteOnExit();
-                       }
-               }
-               
-               // Let the listeners know that an app has been installed
-               fireAppsChangedEvent();
        }
        
        /**
@@ -393,16 +441,20 @@
         */
        public void uninstallApp(App app) throws AppUninstallException {
                
-               app.uninstall(this);
-               
-               // Let the listeners know that an app has been uninstalled
-               fireAppsChangedEvent();
+               try {
+                       app.moveAppFile(this, new 
File(getUninstalledAppsPath()));
+               } catch (IOException e) {
+                       throw new AppUninstallException("Unable to move app 
file, " + e.getMessage());
+               }
        }
 
-    public void disableApp(App app) {
+    public void disableApp(App app) throws AppDisableException {
                
-               // Let the listeners know that an app has been disabled
-               fireAppsChangedEvent();
+       try {
+                       app.moveAppFile(this, new File(getDisabledAppsPath()));
+               } catch (IOException e) {
+                       throw new AppDisableException("Unable to move app file, 
" + e.getMessage());
+               }
     }
        
        private void fireAppsChangedEvent() {
@@ -546,20 +598,12 @@
        
        
        public String getKarafDeployDirectory() {
-               Object property = System.getProperties().get("cytoscape.home");
+               File directory = new File(System.getProperty("user.home") + 
File.separator + ".cytoscape" + File.separator + "3.0"
+                               + File.separator + "apps" + File.separator + 
"deploy");
                
-               // Temporary fix -- will still allow app-impl to start even if 
failed to obtain Karaf deploy directory
-               if (property == null) {
-                       File tempPath = new File(getDownloadedAppsPath() + 
File.separator + "temp");
-                       tempPath.mkdirs();
-                       return tempPath.getAbsolutePath();
-               }
-
-               String current = property.toString();
-               String deployDirectoryPath = current + File.separator + 
"framework" 
-                       + File.separator + "deploy";
+               directory.mkdirs();
                
-               return deployDirectoryPath;
+               return directory.getAbsolutePath();
        }
        
        public void cleanKarafDeployDirectory() {

Modified: 
core3/impl/trunk/app-impl/src/main/java/org/cytoscape/app/internal/manager/AppParser.java
===================================================================
--- 
core3/impl/trunk/app-impl/src/main/java/org/cytoscape/app/internal/manager/AppParser.java
   2012-07-24 21:17:27 UTC (rev 29977)
+++ 
core3/impl/trunk/app-impl/src/main/java/org/cytoscape/app/internal/manager/AppParser.java
   2012-07-24 23:20:54 UTC (rev 29978)
@@ -56,7 +56,7 @@
         * @throws AppParsingException If there was an error during parsing, 
such as missing data from the manifest file
         */
        public App parseApp(File file) throws AppParsingException {
-               App parsedApp = new SimpleApp();
+               App parsedApp = new SimpleAppOld();
                
                DebugHelper.print("Parsing: " + file.getPath());
                
@@ -113,7 +113,7 @@
                        }
                } else if (osgiMetadataFound) {
                        bundleApp = true;
-                       parsedApp = new KarafArchiveApp();
+                       parsedApp = new BundleApp();
                }
                
                // Attempt to obtain manifest file from jar
@@ -133,52 +133,52 @@
                // Bundle apps are instantiated by OSGi using their activator 
classes
                if (!bundleApp) {
                        // Obtain the fully-qualified name of the class to 
instantiate upon app installation
-                       entryClassName = 
manifest.getMainAttributes().getValue(SimpleApp.APP_CLASS_TAG);
+                       entryClassName = 
manifest.getMainAttributes().getValue(SimpleAppOld.APP_CLASS_TAG);
                        if (entryClassName == null || 
entryClassName.trim().length() == 0) {
-                               throw new AppParsingException("Jar is missing 
value for entry " + SimpleApp.APP_CLASS_TAG + " in its manifest file.");
+                               throw new AppParsingException("Jar is missing 
value for entry " + SimpleAppOld.APP_CLASS_TAG + " in its manifest file.");
                        }
                }
                
                // Obtain the human-readable name of the app
-               String readableName = 
manifest.getMainAttributes().getValue(SimpleApp.APP_READABLE_NAME_TAG);
+               String readableName = 
manifest.getMainAttributes().getValue(SimpleAppOld.APP_READABLE_NAME_TAG);
                if (readableName == null || readableName.trim().length() == 0) {
                        
                        if (bundleApp) {
                                readableName = "Name-not-found: karaf/" + 
file.getName();
                        } else {
-                               throw new AppParsingException("Jar is missing 
value for entry " + SimpleApp.APP_READABLE_NAME_TAG + " in its manifest file.");
+                               throw new AppParsingException("Jar is missing 
value for entry " + SimpleAppOld.APP_READABLE_NAME_TAG + " in its manifest 
file.");
                                // readableName = "unnamed";
                        }
                }
                
                // Obtain the version of the app, in major.minor.patch[-tag] 
format, ie. 3.0.0-SNAPSHOT or 1.2.3
-               String appVersion = 
manifest.getMainAttributes().getValue(SimpleApp.APP_VERSION_TAG);
+               String appVersion = 
manifest.getMainAttributes().getValue(SimpleAppOld.APP_VERSION_TAG);
                if (appVersion == null || appVersion.trim().length() == 0) {
                        
                        if (bundleApp) {
                                appVersion = "Not found";
                        } else {
-                               throw new AppParsingException("Jar is missing 
value for entry " + SimpleApp.APP_VERSION_TAG + " in its manifiest file.");
+                               throw new AppParsingException("Jar is missing 
value for entry " + SimpleAppOld.APP_VERSION_TAG + " in its manifiest file.");
                                // appVersion = "unversioned";
                        }
                        
-               } else if 
(!SimpleApp.APP_VERSION_TAG_REGEX.matcher(appVersion).matches()) {
-                       throw new AppParsingException("The app version 
specified in its manifest file under the key " + SimpleApp.APP_VERSION_TAG
+               } else if 
(!SimpleAppOld.APP_VERSION_TAG_REGEX.matcher(appVersion).matches()) {
+                       throw new AppParsingException("The app version 
specified in its manifest file under the key " + SimpleAppOld.APP_VERSION_TAG
                                        + " was found to not match the format 
major.minor[.patch][-tag], eg. 2.1, 2.1-test, 3.0.0 or 3.0.0-SNAPSHOT");
                }
                
-               String compatibleVersions = 
manifest.getMainAttributes().getValue(SimpleApp.APP_COMPATIBLE_TAG);
+               String compatibleVersions = 
manifest.getMainAttributes().getValue(SimpleAppOld.APP_COMPATIBLE_TAG);
                if (compatibleVersions == null || 
compatibleVersions.trim().length() == 0) {
             if (bundleApp) {
-                logger.warn("Bundle app " + file.getName() + " manifest does 
not contain the entry \"" + SimpleApp.APP_COMPATIBLE_TAG
+                logger.info("Bundle app " + file.getName() + " manifest does 
not contain the entry \"" + SimpleAppOld.APP_COMPATIBLE_TAG
                         + "\". Assuming default value 3.0.");
                 compatibleVersions = "3.0";
             } else {
-                throw new AppParsingException("Jar is missing value for entry 
" + SimpleApp.APP_COMPATIBLE_TAG + " in its manifest file.");
+                throw new AppParsingException("Jar is missing value for entry 
" + SimpleAppOld.APP_COMPATIBLE_TAG + " in its manifest file.");
             }
                } else if 
(!compatibleVersions.matches(APP_COMPATIBLE_TAG_REGEX)) {
                        throw new AppParsingException("The known compatible 
versions of Cytoscape specified in the manifest under the"
-                                       + " key " + 
SimpleApp.APP_COMPATIBLE_TAG + " does not match the form of a comma-delimited 
list of versions of the form"
+                                       + " key " + 
SimpleAppOld.APP_COMPATIBLE_TAG + " does not match the form of a 
comma-delimited list of versions of the form"
                                        + " major[.minor] (eg. 1 or 1.0) with 
variable whitespace around versions");
                }
                

Modified: 
core3/impl/trunk/app-impl/src/main/java/org/cytoscape/app/internal/manager/KarafArchiveApp.java
===================================================================
--- 
core3/impl/trunk/app-impl/src/main/java/org/cytoscape/app/internal/manager/KarafArchiveApp.java
     2012-07-24 21:17:27 UTC (rev 29977)
+++ 
core3/impl/trunk/app-impl/src/main/java/org/cytoscape/app/internal/manager/KarafArchiveApp.java
     2012-07-24 23:20:54 UTC (rev 29978)
@@ -13,6 +13,7 @@
 import org.apache.karaf.features.Feature;
 import org.apache.karaf.features.FeaturesService;
 import org.cytoscape.app.CyAppAdapter;
+import org.cytoscape.app.internal.exception.AppDisableException;
 import org.cytoscape.app.internal.exception.AppInstallException;
 import org.cytoscape.app.internal.exception.AppInstanceException;
 import org.cytoscape.app.internal.exception.AppUninstallException;
@@ -27,6 +28,7 @@
         * Karaf feature information used to install/uninstall a bundle app, 
         * which consists of Karaf features.
         */
+       
        public static class KarafFeature {
                public String featureName;
                public String featureVersion;
@@ -40,6 +42,8 @@
                this.featuresSet = new HashMap<String, KarafFeature>();
        }
        
+       
+       
        @Override
        public Object createAppInstance(CySwingAppAdapter appAdapter)
                        throws AppInstanceException {
@@ -192,6 +196,12 @@
                this.setStatus(AppStatus.TO_BE_UNINSTALLED);
        }
 
+       @Override
+       public void disable(AppManager appManager) throws AppDisableException {
+               // TODO Auto-generated method stub
+               
+       }
+       
        /**
         * Return the list of karaf features.
         * @return The list of karaf features
@@ -203,4 +213,5 @@
        public void setFeaturesList(Map<String, KarafFeature> featuresSet) {
                this.featuresSet = featuresSet;
        }
+
 }

Modified: 
core3/impl/trunk/app-impl/src/main/java/org/cytoscape/app/internal/manager/SimpleApp.java
===================================================================
--- 
core3/impl/trunk/app-impl/src/main/java/org/cytoscape/app/internal/manager/SimpleApp.java
   2012-07-24 21:17:27 UTC (rev 29977)
+++ 
core3/impl/trunk/app-impl/src/main/java/org/cytoscape/app/internal/manager/SimpleApp.java
   2012-07-24 23:20:54 UTC (rev 29978)
@@ -1,54 +1,33 @@
 package org.cytoscape.app.internal.manager;
 
 import java.io.File;
+import java.io.IOException;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLClassLoader;
-import java.util.regex.Pattern;
+import java.util.LinkedList;
 
+import org.apache.commons.io.FileUtils;
+import org.cytoscape.app.AbstractCyApp;
 import org.cytoscape.app.CyAppAdapter;
+import org.cytoscape.app.internal.exception.AppDisableException;
 import org.cytoscape.app.internal.exception.AppInstallException;
 import org.cytoscape.app.internal.exception.AppInstanceException;
 import org.cytoscape.app.internal.exception.AppUninstallException;
 import org.cytoscape.app.swing.CySwingAppAdapter;
 
 public class SimpleApp extends App {
-       /** 
-        * The name of the key in the app jar's manifest file that indicates 
the fully-qualified name 
-        * of the class to instantiate upon app installation. 
-        * */
-       public static final String APP_CLASS_TAG = "Cytoscape-App";
-       
-       /**
-        * The name of the key in the app jar's manifest file indicating the 
human-readable
-        * name of the app
-        */
-       public static final String APP_READABLE_NAME_TAG = "Cytoscape-App-Name";
 
-       /**
-        * The name of the key in the app jar's manifest file indicating the 
version of the app
-        * in the format major.minor.patch[-tag], eg. 3.0.0-SNAPSHOT or 1.2.3
-        */
-       public static final String APP_VERSION_TAG = "Cytoscape-App-Version";
-       
-       /**
-        * The name of the key in the app jar's manifest file indicating the 
major versions of
-        * Cytoscape that the app is known to be compatible with in 
comma-delimited form
-        */
-       public static final String APP_COMPATIBLE_TAG = 
"Cytoscape-API-Compatibility";
-       
-       /**
-        * A regular expression representing valid app versions, which are in 
the format major.minor[.patch][-tag],
-        * eg. 3.0.0-SNAPSHOT, or 3.0.
-        */
-       public static final Pattern APP_VERSION_TAG_REGEX = 
Pattern.compile("(0|([1-9]+\\d*))\\.(\\d)+(\\.(\\d)+)?(-.*)?");
-
        @Override
-       public Object createAppInstance(CySwingAppAdapter appAdapter) throws 
AppInstanceException {
+       public Object createAppInstance(CySwingAppAdapter appAdapter)
+                       throws AppInstanceException {
+               File installFile = this.getAppTemporaryInstallFile();
+               if (installFile == null) {
+                       throw new AppInstanceException("No copy of app jar for 
instancing was found");
+               }
                
-               File installFile = this.getAppTemporaryInstallFile();
                URL appURL = null;
                try {
                        appURL = installFile.toURI().toURL();
@@ -113,20 +92,51 @@
 
        @Override
        public void install(AppManager appManager) throws AppInstallException {
-               // Use the default installation method of copying over the file,
-               // creating an instance, and registering with the app manager.
-               defaultInstall(appManager);
+               if (this.getStatus() == AppStatus.INSTALLED) {
+                       return;
+               }
+               
+               try {
+                       moveAppFile(appManager, new 
File(appManager.getKarafDeployDirectory()));
+               } catch (IOException e) {
+                       throw new AppInstallException("Failed to move app file, 
" + e.getMessage());
+               }
+               
+               // Make a copy used to create app instance
+               LinkedList<String> uniqueNameDirectory = new 
LinkedList<String>();
+               uniqueNameDirectory.add(appManager.getTemporaryInstallPath());
+               
+               try {
+                       if (this.getAppTemporaryInstallFile() == null) {
+                               File targetFile = new 
File(suggestFileName(uniqueNameDirectory, this.getAppFile().getName()));
+                               FileUtils.copyFile(this.getAppFile(), 
targetFile);
+                               this.setAppTemporaryInstallFile(targetFile);
+                       }
+               } catch (IOException e) {
+                       throw new AppInstallException("Unable to make copy of 
app jar for instancing, " + e.getMessage());
+               }
+               
+               try {
+                       if (this.getAppInstance() == null) {
+                               Object appInstance = 
this.createAppInstance(appManager.getSwingAppAdapter());
+                               this.setAppInstance((AbstractCyApp) 
appInstance);
+                       }
+               } catch (AppInstanceException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+               
+               this.setStatus(AppStatus.INSTALLED);
        }
 
        @Override
        public void uninstall(AppManager appManager) throws 
AppUninstallException {
-               
-               // Use the default uninstallation procedure which is to move 
the app to
-               // the uninstalled apps directory
-               defaultUninstall(appManager);
-                               
-               // Simple apps require a Cytoscape restart to be uninstalled
-               setStatus(AppStatus.TO_BE_UNINSTALLED);
+               this.setStatus(AppStatus.UNINSTALLED);
        }
 
+       @Override
+       public void disable(AppManager appManager) throws AppDisableException {
+               this.setStatus(AppStatus.DISABLED);
+       }
+
 }

-- 
You received this message because you are subscribed to the Google Groups 
"cytoscape-cvs" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/cytoscape-cvs?hl=en.

Reply via email to