Search in sources :

Example 1 with Release

use of org.cytoscape.app.internal.net.WebApp.Release in project cytoscape-impl by cytoscape.

the class WebQuerier method downloadApp.

/**
 * Given the unique app name used by the app store, query the app store for the
 * download URL and download the app to the given directory.
 *
 * If a file with the same name exists in the directory, it is overwritten.
 *
 * @param appName The unique app name used by the app store
 * @param version The desired version, or <code>null</code> to obtain the latest release
 * @param directory The directory used to store the downloaded file
 * @param taskMonitor
 */
public File downloadApp(WebApp webApp, String version, File directory, DownloadStatus status) throws AppDownloadException {
    List<WebApp.Release> compatibleReleases = getCompatibleReleases(webApp);
    if (compatibleReleases.size() > 0) {
        WebApp.Release releaseToDownload = null;
        if (version != null) {
            for (WebApp.Release compatibleRelease : compatibleReleases) {
                // Check if the desired version is found in the list of available versions
                if (compatibleRelease.getReleaseVersion().matches("(^\\s*|.*,)\\s*" + version + "\\s*(\\s*$|,.*)")) {
                    releaseToDownload = compatibleRelease;
                }
            }
            if (releaseToDownload == null) {
                throw new AppDownloadException("No release with the requested version " + version + " was found for the requested app " + webApp.getFullName());
            }
        } else {
            releaseToDownload = compatibleReleases.get(compatibleReleases.size() - 1);
        }
        URL downloadUrl = null;
        try {
            downloadUrl = new URL(currentAppStoreUrl + releaseToDownload.getRelativeUrl());
        } catch (MalformedURLException e) {
            throw new AppDownloadException("Unable to obtain URL for version " + version + " of the release for " + webApp.getFullName());
        }
        if (downloadUrl != null) {
            try {
                // Prepare to download
                URLConnection connection = streamUtil.getURLConnection(downloadUrl);
                InputStream inputStream = connection.getInputStream();
                long contentLength = connection.getContentLength();
                ReadableByteChannel readableByteChannel = Channels.newChannel(inputStream);
                File outputFile;
                try {
                    // Replace spaces with underscores
                    String outputFileBasename = webApp.getName().replaceAll("\\s", "_");
                    // Append version information
                    outputFileBasename += "-v" + releaseToDownload.getReleaseVersion();
                    // Strip disallowed characters
                    outputFileBasename = OUTPUT_FILENAME_DISALLOWED_CHARACTERS.matcher(outputFileBasename).replaceAll("");
                    // Append extension
                    outputFileBasename += ".jar";
                    // Output file has same name as app, but spaces and slashes are replaced with hyphens
                    outputFile = new File(directory.getCanonicalPath() + File.separator + outputFileBasename);
                    if (outputFile.exists()) {
                        outputFile.delete();
                    }
                    outputFile.createNewFile();
                    FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
                    try {
                        FileChannel fileChannel = fileOutputStream.getChannel();
                        long currentDownloadPosition = 0;
                        long bytesTransferred;
                        TaskMonitor taskMonitor = status.getTaskMonitor();
                        do {
                            bytesTransferred = fileChannel.transferFrom(readableByteChannel, currentDownloadPosition, 1 << 14);
                            if (status.isCanceled()) {
                                outputFile.delete();
                                return null;
                            }
                            currentDownloadPosition += bytesTransferred;
                            if (contentLength > 0) {
                                double progress = (double) currentDownloadPosition / contentLength;
                                taskMonitor.setProgress(progress);
                            }
                        } while (bytesTransferred > 0);
                    } finally {
                        fileOutputStream.close();
                    }
                } finally {
                    readableByteChannel.close();
                }
                return outputFile;
            } catch (IOException e) {
                throw new AppDownloadException("Error while downloading app " + webApp.getFullName() + ", " + e.getMessage());
            }
        }
    } else {
        throw new AppDownloadException("No available releases were found for the app " + webApp.getFullName() + ".");
    }
    return null;
}
Also used : ReadableByteChannel(java.nio.channels.ReadableByteChannel) MalformedURLException(java.net.MalformedURLException) Release(org.cytoscape.app.internal.net.WebApp.Release) AppDownloadException(org.cytoscape.app.internal.exception.AppDownloadException) InputStream(java.io.InputStream) FileChannel(java.nio.channels.FileChannel) IOException(java.io.IOException) URL(java.net.URL) HttpURLConnection(java.net.HttpURLConnection) URLConnection(java.net.URLConnection) TaskMonitor(org.cytoscape.work.TaskMonitor) FileOutputStream(java.io.FileOutputStream) File(java.io.File) Release(org.cytoscape.app.internal.net.WebApp.Release)

Example 2 with Release

use of org.cytoscape.app.internal.net.WebApp.Release in project cytoscape-impl by cytoscape.

the class WebQuerier method checkForUpdate.

private Update checkForUpdate(App app, String url, AppManager appManager) {
    Set<WebApp> urlApps = appsByUrl.get(url);
    if (urlApps != null) {
        // Look for an app with same name
        for (WebApp webApp : urlApps) {
            if (webApp.getName().equalsIgnoreCase(app.getAppName())) {
                WebApp.Release highestVersionRelease = null;
                for (WebApp.Release release : webApp.getReleases()) {
                    if (highestVersionRelease == null || compareVersions(highestVersionRelease.getReleaseVersion(), release.getReleaseVersion()) > 0) {
                        highestVersionRelease = release;
                    }
                }
                if (highestVersionRelease != null && compareVersions(highestVersionRelease.getReleaseVersion(), app.getVersion()) < 0) {
                    Update update = new Update();
                    update.setUpdateVersion(highestVersionRelease.getReleaseVersion());
                    update.setApp(app);
                    update.setWebApp(webApp);
                    update.setRelease(highestVersionRelease);
                    return update;
                }
            }
        }
    }
    return null;
}
Also used : Release(org.cytoscape.app.internal.net.WebApp.Release)

Example 3 with Release

use of org.cytoscape.app.internal.net.WebApp.Release in project cytoscape-impl by cytoscape.

the class WebQuerier method findAppDescriptions.

public void findAppDescriptions(Set<App> apps) {
    if (appsByUrl.get(DEFAULT_APP_STORE_URL) == null) {
        return;
    }
    // Find the set of all available apps
    Set<WebApp> allWebApps = new HashSet<WebApp>(appsByUrl.get(DEFAULT_APP_STORE_URL).size());
    for (String url : appsByUrl.keySet()) {
        Set<WebApp> urlApps = appsByUrl.get(url);
        for (WebApp webApp : urlApps) {
            allWebApps.add(webApp);
        }
    }
    // Find set of all app releases
    Map<Release, WebApp> allReleases = new HashMap<Release, WebApp>(appsByUrl.get(DEFAULT_APP_STORE_URL).size());
    List<Release> appReleases = null;
    for (WebApp webApp : allWebApps) {
        appReleases = webApp.getReleases();
        for (Release appRelease : appReleases) {
            allReleases.put(appRelease, webApp);
        }
    }
    // Find matching app hashes
    for (Release release : allReleases.keySet()) {
        for (App app : apps) {
            String checksum = app.getSha512Checksum().toLowerCase();
            // in cases where multiple stores give the same hash.
            if (checksum.indexOf(release.getSha512Checksum().toLowerCase()) != -1 && app.getDescription() == null) {
                // WebQuerier obtains app information from app store because no description metadata is required
                // in the app zip file itself. This was to allow better App-Bundle interchangeability, not
                // imposing unneeded restrictions on OSGi bundles (from past discussion on mailing list, some time in 2012)
                // System.out.println("Found description: " + allReleases.get(release).getDescription());
                app.setDescription(allReleases.get(release).getDescription());
            }
        }
    }
}
Also used : App(org.cytoscape.app.internal.manager.App) HashMap(java.util.HashMap) Release(org.cytoscape.app.internal.net.WebApp.Release) HashSet(java.util.HashSet)

Example 4 with Release

use of org.cytoscape.app.internal.net.WebApp.Release in project cytoscape-impl by cytoscape.

the class ResolveAppDependenciesTask method resolveAppDependencies.

private void resolveAppDependencies(App appToInstall) throws Exception {
    CyVersion version = appManager.getCyVersion();
    if (!appToInstall.isCompatible(version))
        throw new Exception("Unable to install " + appToInstall.getAppName() + ".\nIt is incompatible with this version of Cytoscape (" + version.getVersion() + ").");
    taskMonitor.setStatusMessage("Resolving dependencies for " + appToInstall.getAppName() + "...");
    for (App installedApp : appManager.getInstalledApps()) {
        if (installedApp.getAppName().equals(appToInstall.getAppName())) {
            appsToReplace.put(appToInstall, installedApp);
            break;
        }
    }
    dependencyStack.push(appToInstall.getAppName());
    if (appToInstall.getDependencies() != null)
        for (App.Dependency dep : appToInstall.getDependencies()) {
            if (dependencyStack.contains(dep.getName()))
                throw new Exception("Invalid circular dependency: " + dep.getName());
            else if (findAppForDep(dep, appsToInstall) != null)
                continue;
            else if (findAppForDep(dep, appManager.getInstalledApps()) != null)
                continue;
            else {
                App dependencyApp = findAppForDep(dep, appQueue);
                if (dependencyApp != null) {
                    appQueue.remove(dependencyApp);
                } else {
                    Set<WebApp> webApps = appManager.getWebQuerier().getAllApps();
                    if (webApps == null)
                        throw new Exception("Cannot access the App Store to resolve dependencies. Please check your internet connection.");
                    WebApp webApp = findWebAppForDep(dep, webApps);
                    if (webApp == null)
                        throw new Exception("Cannot find dependency: " + dependencyStack.firstElement() + " requires " + dep.getName() + ", which is not available in the App Store");
                    List<Release> releases = webApp.getReleases();
                    Release latestRelease = releases.get(releases.size() - 1);
                    if (WebQuerier.compareVersions(dep.getVersion(), latestRelease.getReleaseVersion()) >= 0) {
                        taskMonitor.setStatusMessage("Downloading dependency for " + dependencyStack.firstElement() + ": " + webApp.getFullName());
                        File appFile = appManager.getWebQuerier().downloadApp(webApp, null, new File(appManager.getDownloadedAppsPath()), status);
                        dependencyApp = appManager.getAppParser().parseApp(appFile);
                    } else
                        throw new Exception("Cannot find dependency: " + dependencyStack.firstElement() + " requires " + dep.getName() + " " + dep.getVersion() + " or later, latest release in App Store is " + latestRelease.getReleaseVersion());
                }
                resolveAppDependencies(dependencyApp);
            }
        }
    dependencyStack.pop();
    appsToInstall.add(appToInstall);
}
Also used : App(org.cytoscape.app.internal.manager.App) WebApp(org.cytoscape.app.internal.net.WebApp) Set(java.util.Set) CyVersion(org.cytoscape.application.CyVersion) ArrayList(java.util.ArrayList) List(java.util.List) LinkedList(java.util.LinkedList) File(java.io.File) Release(org.cytoscape.app.internal.net.WebApp.Release) WebApp(org.cytoscape.app.internal.net.WebApp)

Example 5 with Release

use of org.cytoscape.app.internal.net.WebApp.Release in project cytoscape-impl by cytoscape.

the class WebQuerier method getAllApps.

public Set<WebApp> getAllApps() {
    // If we have a cached result from the previous query, use that one
    if (this.appsByUrl.get(currentAppStoreUrl) != null) {
        return this.appsByUrl.get(currentAppStoreUrl);
    }
    DebugHelper.print("Obtaining apps from app store..");
    Set<WebApp> result = new HashSet<WebApp>();
    String jsonResult = null;
    try {
        // Obtain information about the app from the website
        jsonResult = query(currentAppStoreUrl + "backend/all_apps");
        if (appManager != null && appManager.getAppManagerDialog() != null) {
            appManager.getAppManagerDialog().hideNetworkError();
        }
        // Parse the JSON result
        JSONArray jsonArray = new JSONArray(jsonResult);
        JSONObject jsonObject = null;
        String keyName;
        for (int index = 0; index < jsonArray.length(); index++) {
            jsonObject = jsonArray.getJSONObject(index);
            WebApp webApp = new WebApp();
            keyName = "fullname";
            if (jsonObject.has(keyName)) {
                webApp.setName(jsonObject.get(keyName).toString());
                webApp.setFullName(jsonObject.get(keyName).toString());
            } else {
                continue;
            }
            keyName = "icon_url";
            if (jsonObject.has(keyName)) {
                webApp.setIconUrl(jsonObject.get(keyName).toString());
            }
            keyName = "page_url";
            if (jsonObject.has(keyName)) {
                webApp.setPageUrl(currentAppStoreUrl.substring(0, currentAppStoreUrl.length() - 1) + jsonObject.get(keyName).toString());
            }
            keyName = "description";
            if (jsonObject.has(keyName)) {
                webApp.setDescription(jsonObject.get(keyName).toString());
            }
            keyName = "downloads";
            if (jsonObject.has(keyName)) {
                try {
                    webApp.setDownloadCount(Integer.parseInt(jsonObject.get(keyName).toString()));
                } catch (NumberFormatException e) {
                }
            }
            keyName = "stars_percentage";
            if (jsonObject.has(keyName)) {
                try {
                    webApp.setStarsPercentage(Integer.parseInt(jsonObject.get(keyName).toString()));
                } catch (NumberFormatException e) {
                }
            }
            keyName = "votes";
            if (jsonObject.has(keyName)) {
                try {
                    webApp.setVotes(Integer.parseInt(jsonObject.get(keyName).toString()));
                } catch (NumberFormatException e) {
                }
            }
            keyName = "citation";
            if (jsonObject.has(keyName)) {
                webApp.setCitation(jsonObject.get(keyName).toString());
            }
            try {
                List<WebApp.Release> releases = new LinkedList<WebApp.Release>();
                if (jsonObject.has("releases")) {
                    JSONArray jsonReleases = jsonObject.getJSONArray("releases");
                    JSONObject jsonRelease;
                    boolean isCompatible = true;
                    for (int releaseIndex = 0; releaseIndex < jsonReleases.length(); releaseIndex++) {
                        jsonRelease = jsonReleases.getJSONObject(releaseIndex);
                        WebApp.Release release = new WebApp.Release();
                        release.setBaseUrl(currentAppStoreUrl);
                        release.setRelativeUrl(jsonRelease.optString("release_download_url"));
                        release.setReleaseDate(jsonRelease.optString("created_iso"));
                        release.setReleaseVersion(jsonRelease.optString("version"));
                        release.setSha512Checksum(jsonRelease.optString("hexchecksum"));
                        keyName = "works_with";
                        if (jsonRelease.has(keyName)) {
                            release.setCompatibleCytoscapeVersions(jsonRelease.get(keyName).toString());
                            isCompatible = release.isCompatible(cyVersion);
                        }
                        if (isCompatible)
                            releases.add(release);
                    }
                    // Sort releases by version number
                    Collections.sort(releases, new Comparator<WebApp.Release>() {

                        @Override
                        public int compare(Release first, Release second) {
                            return compareVersions(second.getReleaseVersion(), first.getReleaseVersion());
                        }
                    });
                }
                webApp.setReleases(releases);
            } catch (JSONException e) {
                logger.warn("Error obtaining releases for app: " + webApp.getFullName() + ", " + e.getMessage());
            }
            // DebugHelper.print("Obtaining ImageIcon: " + iconUrlPrefix + webApp.getIconUrl());
            // webApp.setImageIcon(new ImageIcon(new URL(iconUrlPrefix + webApp.getIconUrl())));
            // Check the app for compatible releases
            List<WebApp.Release> compatibleReleases = getCompatibleReleases(webApp);
            // Only add this app if it has compatible releases
            if (compatibleReleases.size() > 0) {
                // Obtain tags associated with this app
                processAppTags(webApp, jsonObject);
                result.add(webApp);
            }
        }
    } catch (final IOException e) {
        if (appManager != null && appManager.getAppManagerDialog() != null) {
            appManager.getAppManagerDialog().showNetworkError();
        }
        e.printStackTrace();
        result = null;
    } catch (JSONException e) {
        // TODO Auto-generated catch block
        DebugHelper.print("Error parsing JSON: " + e.getMessage());
        e.printStackTrace();
    }
    // DebugHelper.print(result.size() + " apps found from web store.");
    // Cache the result of this query
    this.appsByUrl.put(currentAppStoreUrl, result);
    return result;
}
Also used : Release(org.cytoscape.app.internal.net.WebApp.Release) JSONArray(org.json.JSONArray) JSONException(org.json.JSONException) IOException(java.io.IOException) LinkedList(java.util.LinkedList) JSONObject(org.json.JSONObject) Release(org.cytoscape.app.internal.net.WebApp.Release) HashSet(java.util.HashSet)

Aggregations

Release (org.cytoscape.app.internal.net.WebApp.Release)6 File (java.io.File)2 IOException (java.io.IOException)2 HashSet (java.util.HashSet)2 LinkedList (java.util.LinkedList)2 App (org.cytoscape.app.internal.manager.App)2 FileOutputStream (java.io.FileOutputStream)1 InputStream (java.io.InputStream)1 HttpURLConnection (java.net.HttpURLConnection)1 MalformedURLException (java.net.MalformedURLException)1 URL (java.net.URL)1 URLConnection (java.net.URLConnection)1 FileChannel (java.nio.channels.FileChannel)1 ReadableByteChannel (java.nio.channels.ReadableByteChannel)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Set (java.util.Set)1 AppDownloadException (org.cytoscape.app.internal.exception.AppDownloadException)1 WebApp (org.cytoscape.app.internal.net.WebApp)1