Author: paperwing
Date: 2012-05-22 14:00:52 -0700 (Tue, 22 May 2012)
New Revision: 29318

Modified:
   csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/pom.xml
   
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/manager/App.java
   
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/manager/AppManager.java
   
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/net/WebQuerier.java
   
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/ui/CurrentlyInstalledAppsPanel.java
   
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/ui/InstallFromStorePanel.java
   
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/ui/InstallFromStorePanelOld.java
Log:
Updated pom file to remove dynamic import as was done recently with old app 
manager, now able to download and install apps from app store using the app 
listing interface, added method to resolve filename collisions when copying 
files to storage directories

Modified: csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/pom.xml
===================================================================
--- csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/pom.xml   
2012-05-22 19:52:23 UTC (rev 29317)
+++ csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/pom.xml   
2012-05-22 21:00:52 UTC (rev 29318)
@@ -35,14 +35,6 @@
                </resources>
                <plugins>
                        <plugin>
-                               <groupId>org.apache.maven.plugins</groupId>
-                               <artifactId>maven-surefire-plugin</artifactId>
-                               
<version>${maven-surefire-plugin.version}</version>
-                               <configuration>
-                                       
<redirectTestOutputToFile>true</redirectTestOutputToFile>
-                               </configuration>
-                       </plugin>
-                       <plugin>
                                <groupId>org.apache.felix</groupId>
                                <artifactId>maven-bundle-plugin</artifactId>
                                
<version>${maven-bundle-plugin.version}</version>
@@ -54,10 +46,6 @@
                                                
<Export-Package>!${bundle.namespace}.*</Export-Package>
                                                
<Private-Package>${bundle.namespace}.*</Private-Package>
                                                
<Bundle-Activator>${bundle.namespace}.CyActivator</Bundle-Activator>
-                                               <!-- Dynamic import is 
necessary, because it allows apps to
-                                                    access packages that 
aren't imported as because of the code
-                                                    in this bundle. -->
-                                               
<DynamicImport-Package>*</DynamicImport-Package>
                                        </instructions>
                                </configuration>
                        </plugin>

Modified: 
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/manager/App.java
===================================================================
--- 
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/manager/App.java
 2012-05-22 19:52:23 UTC (rev 29317)
+++ 
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/manager/App.java
 2012-05-22 21:00:52 UTC (rev 29318)
@@ -1,8 +1,12 @@
 package org.cytoscape.app.internal.manager;
 
 import java.io.File;
+import java.io.FileDescriptor;
 import java.io.IOException;
 import java.net.URL;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.Set;
 
 import org.apache.commons.io.FileUtils;
 import org.cytoscape.app.AbstractCyApp;
@@ -154,20 +158,71 @@
                try {
                        File appFile = this.getAppFile();
                        
+                       // Make sure no app with the same filename and app name 
is already installed
+                       File installedDirectoryTargetFile = new 
File(installedAppsPath + File.separator + appFile.getName());
+                       File uninstalledDirectoryTargetFile = new 
File(uninstalledAppsPath + File.separator + appFile.getName());
+                       
+                       String copyDestinationFileName = appFile.getName();
+                       
+                       // Check for filename collisions in both the installed 
apps directory as well as the 
+                       // uninstalled apps directory
+                       if (installedDirectoryTargetFile.exists() || 
uninstalledDirectoryTargetFile.exists()) {
+                               Set<App> registeredApps = appManager.getApps();
+                               
+                               // The app registered to the app manager that 
happens to have the same filename
+                               App conflictingApp = null;
+                               
+                               for (App registeredApp : registeredApps) {
+                                       if 
(registeredApp.getAppFile().getName().equalsIgnoreCase(appFile.getName())) {
+                                               conflictingApp = registeredApp;
+                                       }
+                               }
+                               
+                               // Only prevent the overwrite if the filename 
conflict is with an app registered
+                               // to the app manager
+                               if (conflictingApp != null) {
+                                       
+                                       // Check if the apps have the same name
+                                       if 
(this.getAppName().equalsIgnoreCase(conflictingApp.getAppName())) {
+                                               
+                                               // Same filename, same app name 
found
+                                               // return;
+                                               
+                                               Collection<String> 
directoryPaths = new LinkedList<String>();
+                                               
directoryPaths.add(installedAppsPath);
+                                               
directoryPaths.add(uninstalledAppsPath);
+                                               
+                                               copyDestinationFileName = 
suggestFileName(directoryPaths, appFile.getName());
+                                               
+                                       } else {
+                                               
+                                               // Same filename, different app 
name found
+                                               // Rename file
+                                               Collection<String> 
directoryPaths = new LinkedList<String>();
+                                               
directoryPaths.add(installedAppsPath);
+                                               
directoryPaths.add(uninstalledAppsPath);
+                                               
+                                               copyDestinationFileName = 
suggestFileName(directoryPaths, appFile.getName());
+                                       }
+                                       
+                               }
+                       }
+                       
                        // Only perform the copy if the app was not already in 
the target directory
                        if 
(!appFile.getParentFile().getCanonicalPath().equals(installedAppsPath)) {
                                
                                // Uses Apache Commons library; overwrites 
files with the same name.
-                               FileUtils.copyFileToDirectory(appFile, new 
File(installedAppsPath));
+                               // FileUtils.copyFileToDirectory(appFile, new 
File(installedAppsPath));
                                
+                               FileUtils.copyFile(appFile, new 
File(installedAppsPath + File.separator + copyDestinationFileName));
+                               
                                // If we copied it from the uninstalled apps 
directory, remove it from that directory
                                if 
(appFile.getParentFile().getCanonicalPath().equals(uninstalledAppsPath)) {
                                        appFile.delete();
                                }
                                
                                // Update the app's path
-                               String fileName = this.getAppFile().getName();
-                               this.setAppFile(new File(installedAppsPath + 
File.separator + fileName));
+                               this.setAppFile(new File(installedAppsPath + 
File.separator + copyDestinationFileName));
                        }
                } catch (IOException e) {
                        throw new AppInstallException("Unable to copy app file 
to installed apps directory: " + e.getMessage());
@@ -191,6 +246,59 @@
        }
        
        /**
+        * Given a set of canonical directory paths, find a name for a given 
file that does not 
+        * collide with names of files in any of the given directories.
+        * 
+        * For example, if the name file.txt is taken, this method will return 
file-2.txt. If the
+        * latter is taken, it will return file-3.txt, and so on.
+        * 
+        * @param directoryPaths A collection of canonical directory paths used 
to check for files
+        * that have colliding names
+        * @param desiredFileName The desired name for the given file, used as 
a base to which the
+        * number tag is added.
+        * @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) {
+               
+               int postfixNumber = 1;
+               boolean nameCollision = false;
+               File file;
+               
+               for (String directoryPath : directoryPaths) {
+                       file = new File(directoryPath + File.separator + 
desiredFileName);
+                       
+                       nameCollision = nameCollision || (file.exists() && 
!file.isDirectory());
+               }
+               
+               String fileBaseName = desiredFileName;
+               String fileFullExtension = "";
+               int lastPeriodIndex = desiredFileName.lastIndexOf(".");
+               
+               if (lastPeriodIndex != -1) {
+                       fileBaseName = desiredFileName.substring(0, 
lastPeriodIndex);
+                       fileFullExtension = 
desiredFileName.substring(lastPeriodIndex, desiredFileName.length());
+               }
+               
+               String newFileName = desiredFileName;
+               
+               while(nameCollision) {
+                       postfixNumber++;
+                       nameCollision = false;
+                       
+                       for (String directoryPath : directoryPaths) {
+                               // If the old name is basename.extension, then 
the new name is basename-postfixNumber.extension
+                               newFileName = fileBaseName + "-" + 
postfixNumber + fileFullExtension;
+                               file = new File(directoryPath + File.separator 
+ newFileName);
+                               
+                               nameCollision = nameCollision || (file.exists() 
&& !file.isDirectory());
+                       }
+               }
+               
+               return newFileName;
+       }
+       
+       /**
         * Default app uninstallation method that can be used by classes 
extending this class.
         * 
         * The default app uninstallation procedure consists of simply moving 
the app to the uninstalled apps

Modified: 
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/manager/AppManager.java
===================================================================
--- 
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/manager/AppManager.java
  2012-05-22 19:52:23 UTC (rev 29317)
+++ 
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/manager/AppManager.java
  2012-05-22 21:00:52 UTC (rev 29318)
@@ -107,6 +107,14 @@
         */
        public void addApp(App app) {
                apps.add(app);
+               
+               /*
+               // Let the listeners know that an app has changed
+               for (AppsChangedListener appListener : appListeners) {
+                       AppsChangedEvent appEvent = new AppsChangedEvent(this);
+                       appListener.appsChanged(appEvent);
+               }
+               */
        }
        
        /**
@@ -126,17 +134,12 @@
         * Apps that have not been validated are ignored. Also, apps that are 
already installed are left alone.
         * 
         * @param app The {@link App} object representing and providing 
information about the app to install
-        * @throws AppMoveException If there was an IO-related error during the 
copy operation that prevents the app from 
-        * being successfully installed.
+        * @throws AppInstallException If there was an error while attempting 
to install the app such as being
+        * unable to copy the app to the installed apps directory or to 
instance the app's entry point class
         */
-       public void installApp(App app) {
+       public void installApp(App app) throws AppInstallException {
                
-               try {
-                       app.install(this);
-               } catch (AppInstallException e) {
-                       // TODO Auto-generated catch block
-                       e.printStackTrace();
-               }
+               app.install(this);
                
                // Let the listeners know that an app has been installed
                for (AppsChangedListener appListener : appListeners) {
@@ -152,17 +155,13 @@
         * The app will only be uninstalled if it is currently installed.
         * 
         * @param app The app to be uninstalled.
-        * @throws AppMoveException If there was an error while moving the app 
from the installed apps subdirectory
-        * to the subdirectory containing currently uninstalled apps.
+        * @throws AppUninstallException If there was an error while attempting 
to uninstall the app such as
+        * attempting to uninstall an app that isn't installed, or being unable 
to move the app to the uninstalled
+        * apps directory
         */
-       public void uninstallApp(App app) {
+       public void uninstallApp(App app) throws AppUninstallException {
                
-               try {
-                       app.uninstall(this);
-               } catch (AppUninstallException e) {
-                       // TODO Auto-generated catch block
-                       e.printStackTrace();
-               }
+               app.uninstall(this);
                
                // Let the listeners know that an app has been uninstalled
                for (AppsChangedListener appListener : appListeners) {
@@ -247,7 +246,11 @@
                
                // Install each app
                for (App parsedApp : parsedApps) {
-                       installApp(parsedApp);
+                       try {
+                               installApp(parsedApp);
+                       } catch (AppInstallException e) {
+                               System.out.println("Unable to install app: " + 
e.getMessage());
+                       }
                }
                
                System.out.println("Number of apps installed from directory: " 
+ parsedApps.size());

Modified: 
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/net/WebQuerier.java
===================================================================
--- 
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/net/WebQuerier.java
      2012-05-22 19:52:23 UTC (rev 29317)
+++ 
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/net/WebQuerier.java
      2012-05-22 21:00:52 UTC (rev 29318)
@@ -271,7 +271,7 @@
         * 
         * @param appName The unique app name used by the app store 
         */
-       public void downloadApp(String appName, File directory) throws 
AppDownloadException {
+       public File downloadApp(String appName, File directory) throws 
AppDownloadException {
                Set<WebApp> apps = getAllApps();
                
                boolean appFound = false;
@@ -295,27 +295,40 @@
                                
                                System.out.println("Releases for " + appName + 
": " + releases.length());
                                
+                               String latestReleaseUrl = null;
+                               String latestReleaseDate = null;
+                               String releaseDate;
+                               
                                for (int index = 0; index < releases.length(); 
index++) {
                                        JSONObject release = 
releases.getJSONObject(index);
+                               
+                                       releaseDate = 
release.getString("created_iso");
+                                       if (latestReleaseDate == null || 
releaseDate.compareToIgnoreCase(releaseDate) >= 0) {
+                                               latestReleaseUrl = 
APP_STORE_URL + release.getString("release_file_url");
+                                       }
                                }
                                
-                               String url = 
"http://apps.cytoscape.org/media/releases/CyTestSimpleApp1.jar";;
+                               // String url = 
"http://apps.cytoscape.org/media/releases/CyTestSimpleApp1.jar";;
                                
-                               URL downloadUrl = new URL(url);
-                               
-                               ReadableByteChannel readableByteChannel = 
Channels.newChannel(downloadUrl.openStream());
-                               
-                               File outputFile = new 
File(directory.getCanonicalPath() + File.separator + "CyTestSimpleApp1d.jar");
-                               
-                               if (outputFile.exists()) {
-                                       outputFile.delete();
+                               if (latestReleaseUrl != null) {
+                                       URL downloadUrl = new 
URL(latestReleaseUrl);
+                                       
+                                       ReadableByteChannel readableByteChannel 
= Channels.newChannel(downloadUrl.openStream());
+                                       
+                                       File outputFile = new 
File(directory.getCanonicalPath() + File.separator + appName + ".jar");
+                                       
+                                       if (outputFile.exists()) {
+                                               outputFile.delete();
+                                       }
+                                       
+                                       outputFile.createNewFile();
+                                       
+                                   FileOutputStream fileOutputStream = new 
FileOutputStream(outputFile);
+                                   
fileOutputStream.getChannel().transferFrom(readableByteChannel, 0, 1 << 24);
+                                   
+                                   return outputFile;
                                }
-                               
-                               outputFile.createNewFile();
-                               
-                           FileOutputStream fileOutputStream = new 
FileOutputStream(outputFile);
-                           
fileOutputStream.getChannel().transferFrom(readableByteChannel, 0, 1 << 24);
-                               
+                           
                        } catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
@@ -327,6 +340,8 @@
                } else {
                        System.out.println("No app with name " + appName + " 
found.");
                }
+               
+               return null;
        }
        
        public Set<WebApp> getAppsByTag(String tagName) {

Modified: 
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/ui/CurrentlyInstalledAppsPanel.java
===================================================================
--- 
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/ui/CurrentlyInstalledAppsPanel.java
      2012-05-22 19:52:23 UTC (rev 29317)
+++ 
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/ui/CurrentlyInstalledAppsPanel.java
      2012-05-22 21:00:52 UTC (rev 29318)
@@ -9,6 +9,8 @@
 
 import org.cytoscape.app.internal.event.AppsChangedEvent;
 import org.cytoscape.app.internal.event.AppsChangedListener;
+import org.cytoscape.app.internal.exception.AppInstallException;
+import org.cytoscape.app.internal.exception.AppUninstallException;
 import org.cytoscape.app.internal.manager.App;
 import org.cytoscape.app.internal.manager.App.AppStatus;
 import org.cytoscape.app.internal.manager.AppManager;
@@ -146,7 +148,12 @@
         for (App app : selectedApps) {
                // Only install apps that are not already installed
                if (app.getStatus() != AppStatus.INSTALLED) {
-                       appManager.installApp(app);
+                       try {
+                                       appManager.installApp(app);
+                               } catch (AppInstallException e) {
+                                       // TODO Auto-generated catch block
+                                       e.printStackTrace();
+                               }
                }
         }
         
@@ -161,7 +168,12 @@
         for (App app : selectedApps) {
                // Only uninstall apps that are installed
                if (app.getStatus() == AppStatus.INSTALLED) {
-                       appManager.uninstallApp(app);
+                       try {
+                                       appManager.uninstallApp(app);
+                               } catch (AppUninstallException e) {
+                                       // TODO Auto-generated catch block
+                                       e.printStackTrace();
+                               }
                }
         }
         

Modified: 
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/ui/InstallFromStorePanel.java
===================================================================
--- 
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/ui/InstallFromStorePanel.java
    2012-05-22 19:52:23 UTC (rev 29317)
+++ 
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/ui/InstallFromStorePanel.java
    2012-05-22 21:00:52 UTC (rev 29318)
@@ -37,6 +37,7 @@
 import javax.swing.tree.TreePath;
 
 import org.cytoscape.app.internal.exception.AppDownloadException;
+import org.cytoscape.app.internal.exception.AppInstallException;
 import org.cytoscape.app.internal.exception.AppParsingException;
 import org.cytoscape.app.internal.manager.App;
 import org.cytoscape.app.internal.manager.AppManager;
@@ -283,7 +284,12 @@
                                        
                                        // Install the app if parsing was 
successful
                                        if (app != null) {
-                                               appManager.installApp(app);
+                                               try {
+                                                       
appManager.installApp(app);
+                                               } catch (AppInstallException e) 
{
+                                                       
JOptionPane.showMessageDialog(parent, "Error installing app: " + e.getMessage(),
+                                                      "Error", 
JOptionPane.ERROR_MESSAGE);
+                                               }
                                        }
                                }
                }
@@ -347,13 +353,28 @@
         for (WebApp webApp : selectedApps) {
                try {
                        System.out.println("Download path: " + 
appManager.getDownloadedAppsPath());
-                               webQuerier.downloadApp(webApp.getName(), new 
File(appManager.getDownloadedAppsPath()));
+                               
+                       // Download app
+                       File appFile = webQuerier.downloadApp(webApp.getName(), 
new File(appManager.getDownloadedAppsPath()));
+                               
+                       // Parse app
+                       App parsedApp = 
appManager.getAppParser().parseApp(appFile);
+                       
+                       // Install app
+                               appManager.installApp(parsedApp);
+                       
                        } catch (AppDownloadException e) {
-                               // TODO Auto-generated catch block
-                               e.printStackTrace();
+                               JOptionPane.showMessageDialog(parent, "Error 
downloading app: " + e.getMessage(),
+                              "Error", JOptionPane.ERROR_MESSAGE);
+                       } catch (AppParsingException e) {
+                               JOptionPane.showMessageDialog(parent, "Error 
parsing app: " + e.getMessage(),
+                              "Error", JOptionPane.ERROR_MESSAGE);
+                       } catch (AppInstallException e) {
+                               JOptionPane.showMessageDialog(parent, "Error 
installing app: " + e.getMessage(),
+                              "Error", JOptionPane.ERROR_MESSAGE);
                        }
         }
-    }                                                     
+    }     
 
     private void resetButtonActionPerformed(java.awt.event.ActionEvent evt) {
         // TODO add your handling code here:

Modified: 
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/ui/InstallFromStorePanelOld.java
===================================================================
--- 
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/ui/InstallFromStorePanelOld.java
 2012-05-22 19:52:23 UTC (rev 29317)
+++ 
csplugins/trunk/toronto/yuedong/app_manager/impl/app-impl/src/main/java/org/cytoscape/app/internal/ui/InstallFromStorePanelOld.java
 2012-05-22 21:00:52 UTC (rev 29318)
@@ -11,6 +11,8 @@
 import javax.swing.event.ListSelectionListener;
 import javax.swing.filechooser.FileFilter;
 import javax.swing.table.DefaultTableModel;
+
+import org.cytoscape.app.internal.exception.AppInstallException;
 import org.cytoscape.app.internal.exception.AppParsingException;
 import org.cytoscape.app.internal.manager.App;
 import org.cytoscape.app.internal.manager.AppManager;
@@ -235,7 +237,12 @@
                                        
                                        // Install the app if parsing was 
successful
                                        if (app != null) {
-                                               appManager.installApp(app);
+                                               try {
+                                                       
appManager.installApp(app);
+                                               } catch (AppInstallException e) 
{
+                                                       
JOptionPane.showMessageDialog(this, "Error installing app: " + e.getMessage(),
+                                                      "Error", 
JOptionPane.ERROR_MESSAGE);
+                                               }
                                        }
                                }
                }

-- 
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