/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * WekaPackageManager.java * Copyright (C) 2009 University of Waikato, Hamilton, New Zealand */ package weka.core; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.MalformedURLException; import java.net.URI; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.StringTokenizer; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import weka.core.converters.ConverterUtils; import weka.gui.GenericPropertiesCreator; public class WekaPackageManager { private static String WEKAFILES_DIR_NAME = "wekafiles"; public static File WEKA_HOME = new File(System.getProperty("user.home") + File.separator + WEKAFILES_DIR_NAME); public static File PACKAGES_DIR = new File(System.getProperty("user.home") + File.separator + WEKAFILES_DIR_NAME + File.separator + "packages"); private static String PROPERTIES_DIR_NAME = "props"; public static File PROPERTIES_DIR = new File(WEKA_HOME.toString() + File.separator + PROPERTIES_DIR_NAME); //// private static PackageManager PACKAGE_MANAGER = PackageManager.create(); // private static URL REP_URL; // private static URL CACHE_URL; // private static boolean INITIAL_CACHE_BUILD_NEEDED = false; // // static { // establishWekaHome(); // } // // protected static boolean m_wekaHomeEstablished; // protected static boolean m_packagesLoaded; // // protected static boolean establishWekaHome() { // if (m_wekaHomeEstablished) { // return true; // } // // look to see if WEKA_HOME has been defined as an environment // // variable // Environment env = Environment.getSystemWide(); // String wh = env.getVariableValue("WEKA_HOME"); // if (wh != null) { // WEKA_HOME = new File(wh); // PACKAGES_DIR = new File(wh + File.separator + "packages"); // } else { // env.addVariableSystemWide("WEKA_HOME", WEKA_HOME.toString()); // } // // boolean ok = true; // if (!WEKA_HOME.exists()) { // // create it for the user // if (!WEKA_HOME.mkdir()) { // System.err.println("Unable to create WEKA_HOME (" // + WEKA_HOME.getAbsolutePath() + ")"); // ok = false; // } // } // // if (!PACKAGES_DIR.exists()) { // // create the packages dir // if (!PACKAGES_DIR.mkdir()) { // System.err.println("Unable to create packages directory (" // + PACKAGES_DIR.getAbsolutePath() + ")"); // ok = false; // } // } // // m_wekaHomeEstablished = ok; // PACKAGE_MANAGER.setPackageHome(PACKAGES_DIR); // try { // String repURL = env.getVariableValue("weka.core.wekaPackageRepositoryURL"); // if (repURL == null || repURL.length() == 0) { // // See if there is a URL named in $WEKA_HOME/props/PackageRepository.props // File repPropsFile = new File(PROPERTIES_DIR.toString() + File.separator // + "PackageRepository.props"); // // // if (repPropsFile.exists()) { // Properties repProps = new Properties(); // repProps.load(new FileInputStream(repPropsFile)); // repURL = repProps.getProperty("weka.core.wekaPackageRepositoryURL"); // } // } // // if (repURL == null || repURL.length() == 0) { // repURL = "http://weka.sourceforge.net/packageMetaData"; // } else { // System.err.println("weka.core.WekaPackageRepositoryURL = " + repURL); // } // // REP_URL = new URL(repURL); // PACKAGE_MANAGER.setPackageRepositoryURL(REP_URL); // } catch (MalformedURLException ex) { // ex.printStackTrace(); // } catch (IOException ex) { // ex.printStackTrace(); // } // // PACKAGE_MANAGER.setBaseSystemName("weka"); // PACKAGE_MANAGER.setBaseSystemVersion(weka.core.Version.VERSION); // // // Now check the cache and establish it if necessary // File cacheDir = new File(WEKA_HOME.toString() + File.separator // + "repCache"); // try { // String tempCacheString = "file://" + cacheDir.toString(); // // sanitize URI and fix slashes (for Windows) // tempCacheString = tempCacheString.replace(" ", "%20"); // tempCacheString = tempCacheString.replace('\\', '/'); // if (tempCacheString.startsWith("file://") && !tempCacheString.startsWith("file:///")) { // tempCacheString = tempCacheString.substring(7); // tempCacheString = "file:///" + tempCacheString; // } // URI tempURI = new URI(tempCacheString); //// System.err.println(" -- " + tempURI.toString()); // CACHE_URL = tempURI.toURL(); // } catch (Exception e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } // if (!cacheDir.exists()) { // if (!cacheDir.mkdir()) { // System.err.println("Unable to create repository cache directory (" // + cacheDir.getAbsolutePath() + ")"); // CACHE_URL = null; // } else { // // refreshCache(); // INITIAL_CACHE_BUILD_NEEDED = true; // } // } // // return ok; // } // // public static void removeExplorerProps(String installedPackageName) { // try { // Properties expProps = new Properties(); // String explorerProps = getPackageHome().getAbsolutePath() // + File.separator + installedPackageName + File.separator // + "Explorer.props"; // BufferedInputStream bi = new BufferedInputStream(new FileInputStream(explorerProps)); // expProps.load(bi); // bi.close(); // bi = null; // Set keys = expProps.keySet(); // Iterator keysI = keys.iterator(); // while (keysI.hasNext()) { // String key = (String)keysI.next(); // if (!key.endsWith("Policy")) { // // See if this key is in the Explorer props // String existingVal = ExplorerDefaults.get(key, ""); // String toRemove = expProps.getProperty(key); // if (existingVal.length() > 0) { // // cover the case when the value to remove is at the start // // or middle of a list // existingVal = existingVal.replace(toRemove + ",", ""); // // // the case when it's at the end // existingVal = existingVal.replace("," + toRemove, ""); // ExplorerDefaults.set(key, existingVal); // } // } // } // } catch (Exception ex) { // } // } // // protected static void processGenericPropertiesCreatorProps(File propsFile) { // try { // Properties expProps = new Properties(); // BufferedInputStream bi = new BufferedInputStream(new FileInputStream(propsFile)); // expProps.load(bi); // bi.close(); // bi = null; // Properties GPCInputProps = GenericPropertiesCreator.getGlobalInputProperties(); // // Set keys = expProps.keySet(); // Iterator keysI = keys.iterator(); // while (keysI.hasNext()) { // String key = (String)keysI.next(); // // see if this key is in the GPC input props // String existingVal = GPCInputProps.getProperty(key, ""); // if (existingVal.length() > 0) { // // append // String newVal = expProps.getProperty(key); // // only append if this value is not already there!! // if (existingVal.indexOf(newVal) < 0) { // newVal = existingVal + "," + newVal; // GPCInputProps.put(key, newVal); // } // } else { // // simply add this new key/value combo // String newVal = expProps.getProperty(key); // GPCInputProps.put(key, newVal); // } // } // } catch (Exception ex) { // // ignore // } // } // // protected static void processExplorerProps(File propsFile) { // try { // Properties expProps = new Properties(); // BufferedInputStream bi = new BufferedInputStream(new FileInputStream(propsFile)); // expProps.load(bi); // bi.close(); // bi = null; // Set keys = expProps.keySet(); // Iterator keysI = keys.iterator(); // while (keysI.hasNext()) { // String key = (String)keysI.next(); // if (!key.endsWith("Policy")) { // // See if this key is in the Explorer props // String existingVal = ExplorerDefaults.get(key, ""); // if (existingVal.length() > 0) { // // get the replacement policy (if any) // String replacePolicy = expProps.getProperty(key + "Policy"); // if (replacePolicy != null && replacePolicy.length() > 0) { // if (replacePolicy.equalsIgnoreCase("replace")) { // String newVal = expProps.getProperty(key); // ExplorerDefaults.set(key, newVal); // } else { // // default to append // String newVal = expProps.getProperty(key); // // // only append if this value is not already there!! // if (existingVal.indexOf(newVal) < 0) { // newVal = existingVal + "," + newVal; // ExplorerDefaults.set(key, newVal); // } // } // } else { // // default to append // String newVal = expProps.getProperty(key); // // only append if this value is not already there!! // if (existingVal.indexOf(newVal) < 0) { // newVal = existingVal + "," + newVal; // ExplorerDefaults.set(key, newVal); // } // } // } else { // // simply add this new key/value combo // String newVal = expProps.getProperty(key); // ExplorerDefaults.set(key, newVal); // } // } // } // } catch (Exception ex) { // // ignore // } // } // // protected static void processGUIEditorsProps(File propsFile) { // GenericObjectEditor.registerEditors(); // try { // Properties editorProps = new Properties(); // BufferedInputStream bi = new BufferedInputStream(new FileInputStream(propsFile)); // editorProps.load(bi); // bi.close(); // bi = null; // // Enumeration enm = editorProps.propertyNames(); // while (enm.hasMoreElements()) { // String name = enm.nextElement().toString(); // String value = editorProps.getProperty(name, ""); // System.err.println("Registering " + name + " " +value); // GenericObjectEditor.registerEditor(name, value); // } // // } catch (Exception ex) { // // ignore // } // } // // protected static void loadPackageDirectory(File directory, boolean verbose) throws Exception { // File[] contents = directory.listFiles(); // // // make sure that jar files and lib directory get processed first // for (int i = 0; i < contents.length; i++) { // if (contents[i].isFile() && // contents[i].getPath().endsWith(".jar")) { // if (verbose) { // System.out.println("[Weka] loading " + contents[i].getPath()); // } // ClassloaderUtil.addFile(contents[i].getPath()); // } else if (contents[i].isDirectory() && // contents[i].getName().equalsIgnoreCase("lib")) { // // add any jar files in the lib directory to the classpath // loadPackageDirectory(contents[i], verbose); // } // } // // // now any auxilliary files // for (int i = 0; i < contents.length; i++) { // if (contents[i].isFile() && contents[i].getPath().endsWith("Beans.props")) { // // KnowledgeFlow plugin -- add the Beans.props file to the list of // // bean plugin props // // KnowledgeFlowApp.addToPluginBeanProps(contents[i]); // KnowledgeFlowApp.disposeSingleton(); // // } else if (contents[i].isFile() && // contents[i].getPath().endsWith("Explorer.props")) { // // Explorer tabs plugin // // process the keys in the properties file and append/add values // processExplorerProps(contents[i]); // } else if (contents[i].isFile() && // contents[i].getPath().endsWith("GUIEditors.props")) { // // Editor for a particular component // processGUIEditorsProps(contents[i]); // } else if (contents[i].isFile() && // contents[i].getPath().endsWith("GenericPropertiesCreator.props")) { // processGenericPropertiesCreatorProps(contents[i]); // } // /* else if (contents[i].isFile() && // contents[i].getPath().endsWith(".jar")) { // if (verbose) { // System.out.println("[Weka] loading " + contents[i].getPath()); // } // ClassloaderUtil.addFile(contents[i].getPath()); // } else if (contents[i].isDirectory() && // contents[i].getName().equalsIgnoreCase("lib")) { // // add any jar files in the lib directory to the classpath // loadPackageDirectory(contents[i], verbose); // } */ // } // } // // public static boolean loadCheck(Package toLoad, File packageRoot, // PrintStream... progress) { // // // first check against the base version of the system // boolean load; // try { // load = toLoad.isCompatibleBaseSystem(); // } catch (Exception ex) { // ex.printStackTrace(); // return false; // } // // if (!load) { // for (PrintStream p : progress) { // p.println("[Weka] Skipping package " + toLoad.getName() // + " because it is not compatible with Weka " // + PACKAGE_MANAGER.getBaseSystemVersion().toString()); // } // return false; // } // // // first check for missing special files/directories and // // missing external classes (if any) // // if (!(checkForMissingClasses(toLoad, progress) && // checkForMissingFiles(toLoad, packageRoot, progress))) { // return false; // } // // // now check for missing dependencies // try { // List<Dependency> missing = toLoad.getMissingDependencies(); // if (missing.size() > 0) { // for (PrintStream p : progress) { // p.println("[Weka] " + toLoad.getName() + " can't be loaded because the following" + // " packages are missing:"); // for (Dependency d : missing) { // p.println(d.getTarget()); // } // } // return false; // } // } catch (Exception ex) { // ex.printStackTrace(); // return false; // } // // // now check for buggered dependencies // try { // List<Dependency> depends = toLoad.getDependencies(); // for (Dependency d : depends) { // if (d.getTarget().getPackage().isInstalled()) { // if (!loadCheck(d.getTarget().getPackage(), packageRoot, progress)) { // for (PrintStream p : progress) { // p.println("[Weka] Can't load " + toLoad.getName() + " because " + // d.getTarget() + " can't be loaded."); // } // return false; // } // } // } // } catch (Exception ex) { // ex.printStackTrace(); // return false; // } // // // return true; // } // // /** // * Checks to see if there are any classes that we should try to instantiate // * before allowing this package to be loaded. This is useful for checking // * to see if third-party classes are accessible. An example would be // * Java3D, which has an installer that installs into the JRE/JDK. // * // * @param toLoad the package to check // * @return true if good to go // */ // public static boolean checkForMissingClasses(Package toLoad, // PrintStream... progress) { // boolean result = true; // Object doNotLoadIfClassNotInstantiable = // toLoad.getPackageMetaDataElement("DoNotLoadIfClassNotPresent"); // // if (doNotLoadIfClassNotInstantiable != null && // doNotLoadIfClassNotInstantiable.toString().length() > 0) { // // StringTokenizer tok = new StringTokenizer(doNotLoadIfClassNotInstantiable.toString(), ","); // while (tok.hasMoreTokens()) { // String nextT = tok.nextToken().trim(); // try { // Class.forName(nextT); // } catch (Exception ex) { // for (PrintStream p : progress) { // p.println("[Weka] " + toLoad.getName() + " can't be loaded because " // + nextT + " can't be instantiated."); // } // result = false; // break; // } // } // } // // if (!result) { // // grab the message to print to the log (if any) // Object doNotLoadMessage = // toLoad.getPackageMetaDataElement("DoNotLoadIfClassNotPresentMessage"); // if (doNotLoadMessage != null && doNotLoadMessage.toString().length() > 0) { // for (PrintStream p : progress) { // String dnlM = doNotLoadMessage.toString(); // try { // dnlM = Environment.getSystemWide().substitute(dnlM); // } catch (Exception e) { // // quietly ignore // } // p.println("[Weka] " + dnlM); // } // } // } // // return result; // } // // /** // * Checks to see if there are any missing files/directories for a // * given package. If there are missing files, then the package can't // * be loaded. An example would be a connector package that, for whatever // * reason, can't include a necessary third-party jar file in its lib // * folder, and requires the user to download and install this jar file // * manually. // * // * @param toLoad the package to check // * @param packageRoot the root directory of the package // * @return true if good to go // */ // public static boolean checkForMissingFiles(Package toLoad, // File packageRoot, PrintStream... progress) { // boolean result = true; // // Object doNotLoadIfFileMissing = // toLoad.getPackageMetaDataElement("DoNotLoadIfFileNotPresent"); // String packageRootPath = packageRoot.getPath() + File.separator; // // if (doNotLoadIfFileMissing != null && // doNotLoadIfFileMissing.toString().length() > 0) { // // StringTokenizer tok = new StringTokenizer(doNotLoadIfFileMissing.toString(), ","); // while (tok.hasMoreTokens()) { // String nextT = tok.nextToken().trim(); // File toCheck = new File(packageRootPath + nextT); // if (!toCheck.exists()) { // for (PrintStream p : progress) { // p.println("[Weka] " + toLoad.getName() + " can't be loaded because " // + toCheck.getPath() + " appears to be missing."); // } // result = false; // break; // } // } // } // // if (!result) { // // grab the message to print to the log (if any) // Object doNotLoadMessage = // toLoad.getPackageMetaDataElement("DoNotLoadIfFileNotPresentMessage"); // if (doNotLoadMessage != null && doNotLoadMessage.toString().length() > 0) { // String dnlM = doNotLoadMessage.toString(); // try { // dnlM = Environment.getSystemWide().substitute(dnlM); // } catch (Exception ex) { // // quietly ignore // } // for (PrintStream p : progress) { // p.println("[Weka] " + dnlM); // } // } // } // // return result; // } // // public static synchronized void loadPackages(boolean verbose) { // loadPackages(verbose, true); // } // // public static synchronized void loadPackages(boolean verbose, boolean refreshGOEProperties) { // if (m_packagesLoaded) { // return; // } // // m_packagesLoaded = true; // if (establishWekaHome()) { // // try and load any jar files and add to the classpath // File[] contents = PACKAGES_DIR.listFiles(); // for (int i = 0 ; i < contents.length; i++) { // if (contents[i].isDirectory()) { // try { // Package toLoad = getInstalledPackageInfo(contents[i].getName()); // boolean load; // // Only perform the check against the current version of Weka if there exists // // a Description.props file // if (toLoad != null) { // // load = loadCheck(toLoad, contents[i], System.err); // /* // check to see if any of the DoNotLoad keys are present // load = checkForMissingClasses(toLoad, System.err); // // if (load) { // load = checkForMissingFiles(toLoad, contents[i], // System.err); // } */ // if (load) { // if (verbose) { // System.out.println("[Weka] loading package " + contents[i].getName()); // } // loadPackageDirectory(contents[i], verbose); // } // } // } catch (Exception ex) { // ex.printStackTrace(); // System.err.println("[Weka] Problem loading package " + contents[i].getName() // + " skipping..."); // } // } // } // } // // // do we need to regenerate the list of available schemes for // // the GUIs (this is not necessary when executing stuff from // // the command line // if (refreshGOEProperties) { // refreshGOEProperties(); // } // } // // public static void refreshGOEProperties() { // ClassDiscovery.clearClassCache(); // GenericPropertiesCreator.regenerateGlobalOutputProperties(); // GenericObjectEditor.determineClasses(); // ConverterUtils.initialize(); // KnowledgeFlowApp.disposeSingleton(); // KnowledgeFlowApp.reInitialize(); // } // // public static PackageManager getUnderlyingPackageManager() { // return PACKAGE_MANAGER; // } // // /** // * Get the number of packages that are available at the repository. // * // * @return the number of packages that are available (or -1 if this // * can't be determined for some reason. // */ // public static int numRepositoryPackages() { // int numPackages = -1; // try { // PACKAGE_MANAGER.setPackageRepositoryURL(REP_URL); // String numPackagesS = PACKAGE_MANAGER.getPackageRepositoryURL().toString() // + "/numPackages.txt"; // URLConnection conn = null; // URL connURL = new URL(numPackagesS); // // if (PACKAGE_MANAGER.setProxyAuthentication()) { // conn = connURL.openConnection(PACKAGE_MANAGER.getProxy()); // } else { // conn = connURL.openConnection(); // } // // conn.setConnectTimeout(30000); // timeout after 30 seconds // // BufferedReader bi = // new BufferedReader(new InputStreamReader(conn.getInputStream())); // // String n = bi.readLine(); // numPackages = Integer.parseInt(n); // bi.close(); // // } catch (Exception ex) { // ex.printStackTrace(); // } // // return numPackages; // } // // /** // * Just get a list of the package names. // * This is faster than calling getAllPackages(), especially // * if fetching from the online repository, since the full meta // * data for each package doesn't have to be read. // * // * @param local true if the local package list in the cache should // * be read rather than the online repository // * // * @return a Map<String, String> of all the package names available either // * locally or at the repository // */ // public static Map<String, String> getPackageList(boolean local) { // Map<String, String> result = new HashMap<String, String>(); // // try { // useCacheOrOnlineRepository(); // // if (!local) { // PACKAGE_MANAGER.setPackageRepositoryURL(REP_URL); // } // // String packageListS = PACKAGE_MANAGER.getPackageRepositoryURL().toString() // + "/packageList.txt"; // URLConnection conn = null; // URL connURL = new URL(packageListS); // // if (PACKAGE_MANAGER.setProxyAuthentication()) { // conn = connURL.openConnection(PACKAGE_MANAGER.getProxy()); // } else { // conn = connURL.openConnection(); // } // // conn.setConnectTimeout(30000); // timeout after 30 seconds // // BufferedReader bi = // new BufferedReader(new InputStreamReader(conn.getInputStream())); // String l = null; // while ((l = bi.readLine()) != null) { // result.put(l,l); // } // bi.close(); // // } catch (Exception ex) { // ex.printStackTrace(); // result = null; // } // // return result; // } // // public static Exception establishCacheIfNeeded(PrintStream... progress) { // Exception problem = null; // if (INITIAL_CACHE_BUILD_NEEDED) { // for (PrintStream p : progress) { // p.println("Caching repository meta data, please wait..."); // } // // problem = refreshCache(progress); // // INITIAL_CACHE_BUILD_NEEDED = false; // } // return problem; // } // // public static Exception checkForNewPackages(PrintStream... progress) { // Exception problem = null; // // Map<String, String> localPackageNameList = getPackageList(true); // // if (localPackageNameList == null) { // // quietly return and see if we can continue anyway // return null; // } // // Map<String, String> repositoryPackageNameList = getPackageList(false); // // if (repositoryPackageNameList == null) { // // quietly return and see if we can continue anyway // return null; // } // // if (repositoryPackageNameList.keySet().size() != // localPackageNameList.keySet().size()) { // // package(s) have disappeared from the repository. // // Force a cache refresh... // if (repositoryPackageNameList.keySet().size() < // localPackageNameList.keySet().size()) { // for (PrintStream p : progress) { // p.println("Some packages no longer exist at the repository. " + // "Refreshing cache..."); // } // } else { // for (PrintStream p : progress) { // p.println("There are new packages at the repository. " + // "Refreshing cache..."); // } // } // problem = refreshCache(progress); // } // // return problem; // } // // public static Exception refreshCache(PrintStream... progress) { // Exception problem = null; // if (CACHE_URL == null) { // return null; // } // // PACKAGE_MANAGER.setPackageRepositoryURL(REP_URL); // String cacheDir = WEKA_HOME.toString() + File.separator // + "repCache"; // try { // for (PrintStream p : progress) { // p.println("Refresh in progress. Please wait..."); // } // byte[] zip = PACKAGE_MANAGER.getRepositoryPackageMetaDataOnlyAsZip(progress); // // /*File tempF = new File(WEKA_HOME.toString() + File.separator // + "repCache/rep.zip"); // BufferedOutputStream bos = // new BufferedOutputStream(new FileOutputStream(tempF)); // bos.write(zip); // bos.close();*/ // // ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(zip)); // ZipEntry ze; // final byte[] buff = new byte[1024]; // while ((ze = zis.getNextEntry()) != null) { //// System.out.println("Cache: inflating " + ze.getName()); // if (ze.isDirectory()) { // new File(cacheDir, ze.getName()).mkdir(); // continue; // } // BufferedOutputStream bo = // new BufferedOutputStream(new FileOutputStream(new File(cacheDir, ze.getName()))); // while (true) { // int amountRead = zis.read(buff); // if (amountRead == -1) { // break; // } // // write the data here // bo.write(buff, 0, amountRead); // } // bo.close(); // } // } catch (Exception e) { // e.printStackTrace(); // // // OK, we have a problem with the repository cache - use // // the repository itself instead and delete repCache // CACHE_URL = null; // try { // DefaultPackageManager.deleteDir(new File(cacheDir), System.out); // } catch (Exception e1) { // // TODO Auto-generated catch block // e1.printStackTrace(); // } // // return e; // } // // return problem; // } // // public static boolean installedPackageResourceExists(String packageName, // String resourceName) { // // String fullResourcePath = getPackageHome().toString() // + File.separator + packageName + File.separator + resourceName; // // return new File(fullResourcePath).exists(); // } // // private static void useCacheOrOnlineRepository() { // if (CACHE_URL != null) { // PACKAGE_MANAGER.setPackageRepositoryURL(CACHE_URL); // } else { // PACKAGE_MANAGER.setPackageRepositoryURL(REP_URL); // } // } // // public static File getPackageHome() { // return PACKAGE_MANAGER.getPackageHome(); // } // // /** // * Find the most recent version of the package encapsulated in the // * supplied PackageConstraint argument that satisfies the constraint // * // * @param toCheck the PackageConstraint containing the package in question // * @return the most recent version of the package satisfying the constraint // * @throws Exception if a version can't be found that satisfies the constraint // * or an error occurs while communicating with the respository // */ // public static Package mostRecentVersionWithRespectToConstraint(PackageConstraint toCheck) // throws Exception { // Package target = toCheck.getPackage(); // Package result = null; // // // List<Object> availableVersions = // PACKAGE_MANAGER.getRepositoryPackageVersions(target.getName()); // // // version numbers will be in descending sorted order from the repository // // we want the most recent version that meets the target constraint // for (Object version : availableVersions) { // Package candidate = PACKAGE_MANAGER.getRepositoryPackageInfo(target.getName(), version); // if (toCheck.checkConstraint(candidate)) { // /*System.out.println("**** Most recent version of " + target.getName() // + "that meets the constraint " + toCheck.toString() + " is " // + candidate.toString()); */ // result = candidate; // break; // } // } // // if (result == null) { // throw new Exception("[WekaPackageManager] unable to find a version of " + // "package " + target.getName() + " that meets constraint " + // toCheck.toString()); // } // // return result; // } // // public static void installPackages(List<Package> toInstall, // PrintStream... progress) throws Exception { // // useCacheOrOnlineRepository(); // PACKAGE_MANAGER.installPackages(toInstall, progress); // // for (Package p : toInstall) { // // String packageName = p.getName(); // File packageDir = new File(PACKAGE_MANAGER.getPackageHome().toString() + File.separator // + packageName); // // boolean loadIt = loadCheck(p, packageDir, progress); // // if (loadIt) { // loadPackageDirectory(packageDir, false); // } // } // } // // public static List<Object> getRepositoryPackageVersions(String packageName) throws Exception { // useCacheOrOnlineRepository(); // return PACKAGE_MANAGER.getRepositoryPackageVersions(packageName); // } // // public static URL getPackageRepositoryURL() { // useCacheOrOnlineRepository(); // return PACKAGE_MANAGER.getPackageRepositoryURL(); // } // // public static List<Package> getAllPackages() throws Exception { // useCacheOrOnlineRepository(); // return PACKAGE_MANAGER.getAllPackages(); // } // // public static List<Package> getAvailablePackages() throws Exception { // useCacheOrOnlineRepository(); // return PACKAGE_MANAGER.getAvailablePackages(); // } // // public static List<Package> getInstalledPackages() throws Exception { // useCacheOrOnlineRepository(); // return PACKAGE_MANAGER.getInstalledPackages(); // } // // public static List<Dependency> getAllDependenciesForPackage(Package target, // Map<String, List<Dependency>> conflicts) throws Exception { // useCacheOrOnlineRepository(); // return PACKAGE_MANAGER.getAllDependenciesForPackage(target, conflicts); // } // // public static Package getPackageArchiveInfo(String packageArchivePath) throws Exception { // useCacheOrOnlineRepository(); // return PACKAGE_MANAGER.getPackageArchiveInfo(packageArchivePath); // } // // public static Package getInstalledPackageInfo(String packageName) throws Exception { // useCacheOrOnlineRepository(); // return PACKAGE_MANAGER.getInstalledPackageInfo(packageName); // } // // public static Package getRepositoryPackageInfo(String packageName) throws Exception { // useCacheOrOnlineRepository(); // return PACKAGE_MANAGER.getRepositoryPackageInfo(packageName); // } // // public static Package getRepositoryPackageInfo(String packageName, String version) // throws Exception { // useCacheOrOnlineRepository(); // return PACKAGE_MANAGER.getRepositoryPackageInfo(packageName, version); // } // // public static void installPackageFromRepository(String packageName, // String version, PrintStream... progress) // throws Exception { // useCacheOrOnlineRepository(); // Package toLoad = getRepositoryPackageInfo(packageName); // // Object specialInstallMessage = // toLoad.getPackageMetaDataElement("MessageToDisplayOnInstallation"); // if (specialInstallMessage != null && // specialInstallMessage.toString().length() > 0) { // String siM = specialInstallMessage.toString(); // try { // siM = Environment.getSystemWide().substitute(siM); // } catch (Exception ex) { // // quietly ignore // } // String message = "**** Special installation message ****\n" // + siM // + "\n**** Special installation message ****"; // for (PrintStream p : progress) { // p.println(message); // } // } // // PACKAGE_MANAGER.installPackageFromRepository(packageName, version, progress); // File packageDir = new File(PACKAGE_MANAGER.getPackageHome().toString() + File.separator // + packageName); // // boolean loadIt = checkForMissingClasses(toLoad, progress); // if (loadIt) { // File packageRoot = // new File(PACKAGE_MANAGER.getPackageHome() + File.separator // + packageName); // loadIt = checkForMissingFiles(toLoad, packageRoot, progress); // if (loadIt) { // loadPackageDirectory(packageDir, false); // } // } // } // // public static String installPackageFromArchive(String packageArchivePath, // PrintStream... progress) throws Exception { // useCacheOrOnlineRepository(); // Package toInstall = PACKAGE_MANAGER.getPackageArchiveInfo(packageArchivePath); // // Object specialInstallMessage = // toInstall.getPackageMetaDataElement("MessageToDisplayOnInstallation"); // if (specialInstallMessage != null && // specialInstallMessage.toString().length() > 0) { // String siM = specialInstallMessage.toString(); // try { // siM = Environment.getSystemWide().substitute(siM); // } catch (Exception ex) { // // quietly ignore // } // String message = "**** Special installation message ****\n" // + siM // + "\n**** Special installation message ****"; // for (PrintStream p : progress) { // p.println(message); // } // } // // PACKAGE_MANAGER.installPackageFromArchive(packageArchivePath, progress); // // boolean loadIt = checkForMissingClasses(toInstall, progress); // if (loadIt) { // File packageRoot = // new File(PACKAGE_MANAGER.getPackageHome() + File.separator // + toInstall.getName()); // loadIt = checkForMissingFiles(toInstall, packageRoot, progress); // if (loadIt) { // loadPackageDirectory(packageRoot, false); // } // } // // return toInstall.getName(); // } // // public static String installPackageFromURL(URL packageURL, PrintStream... progress) throws Exception { // useCacheOrOnlineRepository(); // String packageName = PACKAGE_MANAGER.installPackageFromURL(packageURL, progress); // // Package installed = PACKAGE_MANAGER.getInstalledPackageInfo(packageName); // // Object specialInstallMessage = // installed.getPackageMetaDataElement("MessageToDisplayOnInstallation"); // if (specialInstallMessage != null && // specialInstallMessage.toString().length() > 0) { // String message = "**** Special installation message ****\n" // + specialInstallMessage.toString() // + "\n**** Special installation message ****"; // for (PrintStream p : progress) { // p.println(message); // } // } // // boolean loadIt = checkForMissingClasses(installed, progress); // if (loadIt) { // File packageRoot = // new File(PACKAGE_MANAGER.getPackageHome() + File.separator // + installed.getName()); // loadIt = checkForMissingFiles(installed, packageRoot, progress); // if (loadIt) { // loadPackageDirectory(packageRoot, false); // } // } // return packageName; // } // // public static void uninstallPackage(String packageName, boolean updateKnowledgeFlow, // PrintStream... progress) // throws Exception { // // // check to see if this is a KnowledgeFlow package (presence of Beans.props file) // if (updateKnowledgeFlow) { // File packageToDel = new File(PACKAGE_MANAGER.getPackageHome().toString() + File.separator // + packageName); // if (packageToDel.exists() && packageToDel.isDirectory()) { // File[] contents = packageToDel.listFiles(); // for (int i = 0; i < contents.length; i++) { // if (contents[i].isFile() && contents[i].getPath().endsWith("Beans.props")) { // // KnowledgeFlow plugin -- remove this properties file from the list of // // bean plugin props // // KnowledgeFlowApp.removeFromPluginBeanProps(contents[i]); // KnowledgeFlowApp.disposeSingleton(); // break; // } // } // } // } // // PACKAGE_MANAGER.uninstallPackage(packageName, progress); // } // // private static void printPackageInfo(Map<?,?> packageProps) { // Set<?> keys = packageProps.keySet(); // Iterator<?> i = keys.iterator(); // // while (i.hasNext()) { // Object key = i.next(); // Object value = packageProps.get(key); // System.out.println(Utils.padLeft(key.toString(), 11) + ":\t" + value.toString()); // } // } // // protected static void printPackageArchiveInfo(String packagePath) throws Exception { // Map<?,?> packageProps = getPackageArchiveInfo(packagePath).getPackageMetaData(); // printPackageInfo(packageProps); // } // // protected static void printInstalledPackageInfo(String packageName) throws Exception { // Map<?,?> packageProps = getInstalledPackageInfo(packageName).getPackageMetaData(); // printPackageInfo(packageProps); // } // // protected static void printRepositoryPackageInfo(String packageName, // String version) throws Exception { // Map<?,?> packageProps = getRepositoryPackageInfo(packageName, version).getPackageMetaData(); // printPackageInfo(packageProps); // } // // private static String queryUser() { // java.io.BufferedReader br = // new java.io.BufferedReader(new java.io.InputStreamReader(System.in)); // // String result = null; // try { // result = br.readLine(); // } catch (java.io.IOException ex) { // // ignore // } // // return result; // } // // private static void removeInstalledPackage(String packageName, boolean force, // PrintStream... progress) throws Exception { // // List<Package> compromised = new ArrayList<Package>(); // // // Now check to see which other installed packages depend on this one // List<Package> installedPackages = null; // if (!force) { // installedPackages = getInstalledPackages(); // for (Package p : installedPackages) { // List<Dependency> tempDeps = p.getDependencies(); // // for (Dependency d : tempDeps) { // if (d.getTarget().getPackage().getName().equals(packageName)) { // // add this installed package to the list // compromised.add(p); // break; // } // } // } // // if (compromised.size() > 0) { // System.out.println("The following installed packages depend on " // + packageName + " :\n"); // for (Package p : compromised) { // System.out.println("\t" + p.getName()); // } // // System.out.println("\nDo you wish to proceed [y/n]?"); // String response = queryUser(); // if (response != null && (response.equalsIgnoreCase("n") || // response.equalsIgnoreCase("no"))) { // return; // bail out here // } // } // } // // if (force) { // System.out.println("Forced uninstall."); // } // // compromised = null; // installedPackages = null; // // uninstallPackage(packageName, false, progress); // } // // private static void installPackageFromRepository(String packageName, String version, // boolean force) throws Exception { // // Package toInstall = null; // try { // toInstall = getRepositoryPackageInfo(packageName, version); // } catch (Exception ex) { // System.err.println("[WekaPackageManager] Package " + packageName + " at version " + version // + " doesn't seem to exist!"); // //System.exit(1); // return; // } // // First check to see if this package is compatible with the base system // // if (!force) { // boolean ok = toInstall.isCompatibleBaseSystem(); // // if (!ok) { // List<Dependency> baseSysDep = toInstall.getBaseSystemDependency(); // StringBuffer depList = new StringBuffer(); // for (Dependency bd : baseSysDep) { // depList.append(bd.getTarget().toString() + " "); // } // System.err.println("Can't install package " + packageName // + " because it requires " + depList.toString()); // return; // } // // // true if this package is already installed. In which case we need to check // // if changing this package will impact other already installed packages // boolean upOrDowngrading = false; // if (toInstall.isInstalled()) { // Package installedVersion = getInstalledPackageInfo(packageName); // if (!toInstall.equals(installedVersion)) { // // System.out.println("Package " + packageName + "[" + installedVersion // + "] is already installed. Replace with " + toInstall +" [y/n]?"); // // String response = queryUser(); // if (response != null && (response.equalsIgnoreCase("n") || // response.equalsIgnoreCase("no"))) { // return; // bail out here // } // upOrDowngrading = true; // } else { // System.out.println("Package " + packageName + "[" + installedVersion // + "] is already installed. Install again [y/n]?"); // String response = queryUser(); // if (response != null && (response.equalsIgnoreCase("n") || // response.equalsIgnoreCase("no"))) { // return; // bail out here // } // } // } // // // Now get a full list of dependencies for this package and // // check for any conflicts // Map<String, List<Dependency>> conflicts = new HashMap<String, List<Dependency>>(); // List<Dependency> dependencies = getAllDependenciesForPackage(toInstall, conflicts); // // if (conflicts.size() > 0) { // System.err.println("Package " + packageName + " requires the following packages:\n"); // Iterator<Dependency> depI = dependencies.iterator(); // while (depI.hasNext()) { // Dependency d = depI.next(); // System.err.println("\t" + d); // } // // System.err.println("\nThere are conflicting dependencies:\n"); // Set<String> pNames = conflicts.keySet(); // Iterator<String> pNameI = pNames.iterator(); // while (pNameI.hasNext()) { // String pName = pNameI.next(); // System.err.println("Conflicts for " + pName); // List<Dependency> confsForPackage = conflicts.get(pName); // Iterator<Dependency> confs = confsForPackage.iterator(); // while (confs.hasNext()) { // Dependency problem = confs.next(); // System.err.println("\t" + problem); // } // } // // System.err.println("Unable to continue with installation."); // return; // bail out here. // } // // // Next check all dependencies against what is installed and // // inform the user about which installed packages will be altered. Also // // build the list of only those packages that need to be installed or // // upgraded (excluding those that are already installed and are OK). // List<PackageConstraint> needsUpgrade = new ArrayList<PackageConstraint>(); // List<Package> finalListToInstall = new ArrayList<Package>(); // // Iterator<Dependency> depI = dependencies.iterator(); // while (depI.hasNext()) { // Dependency toCheck = depI.next(); // if (toCheck.getTarget().getPackage().isInstalled()) { // String toCheckName = // toCheck.getTarget().getPackage(). // getPackageMetaDataElement("PackageName").toString(); // Package installedVersion = PACKAGE_MANAGER.getInstalledPackageInfo(toCheckName); // if (!toCheck.getTarget().checkConstraint(installedVersion)) { // needsUpgrade.add(toCheck.getTarget()); // Package mostRecent = toCheck.getTarget().getPackage(); // if (toCheck.getTarget() instanceof // org.pentaho.packageManagement.VersionPackageConstraint) { // mostRecent = // WekaPackageManager.mostRecentVersionWithRespectToConstraint(toCheck.getTarget()); // } // finalListToInstall.add(mostRecent); // } // } else { // Package mostRecent = toCheck.getTarget().getPackage(); // if (toCheck.getTarget() instanceof // org.pentaho.packageManagement.VersionPackageConstraint) { // mostRecent = // WekaPackageManager.mostRecentVersionWithRespectToConstraint(toCheck.getTarget()); // } // finalListToInstall.add(mostRecent); // } // } // // if (needsUpgrade.size() > 0) { // System.out.println("The following packages will be upgraded in order to install " // + packageName); // Iterator<PackageConstraint> upI = needsUpgrade.iterator(); // while (upI.hasNext()) { // PackageConstraint tempC = upI.next(); // System.out.println("\t" + tempC); // } // // System.out.print("\nOK to continue [y/n]? > "); // String response = queryUser(); // if (response != null && (response.equalsIgnoreCase("n") || // response.equalsIgnoreCase("no"))) { // return; // bail out here // } // // // now take a look at the other installed packages and see if // // any would have a problem when these ones are upgraded // boolean conflictsAfterUpgrade = false; // List<Package> installed = getInstalledPackages(); // List<Package> toUpgrade = new ArrayList<Package>(); // upI = needsUpgrade.iterator(); // while (upI.hasNext()) { // toUpgrade.add(upI.next().getPackage()); // } // // // add the actual package the user is wanting to install if it // // is going to be an up/downgrade rather than a first install since // // other installed packages may depend on the currently installed version // // and thus could be affected after the up/downgrade // toUpgrade.add(toInstall); // // for (int i = 0; i < installed.size(); i++) { // Package tempP = installed.get(i); // String tempPName = tempP.getName(); // boolean checkIt = true; // for (int j = 0; j < needsUpgrade.size(); j++) { // if (tempPName.equals(needsUpgrade.get(j).getPackage().getName())) { // checkIt = false; // break; // } // } // // if (checkIt) { // List<Dependency> problem = tempP.getIncompatibleDependencies(toUpgrade); // if (problem.size() > 0) { // conflictsAfterUpgrade = true; // // System.err.println("Package " + tempP.getName() + " will have a compatibility" + // "problem with the following packages after upgrading them:"); // Iterator<Dependency> dI = problem.iterator(); // while (dI.hasNext()) { // System.err.println("\t" + dI.next().getTarget().getPackage()); // } // } // } // } // // if (conflictsAfterUpgrade) { // System.err.println("Unable to continue with installation."); // return; // bail out here // } // // } // // if (finalListToInstall.size() > 0) { // System.out.println("To install " + packageName + " the following packages will" + // " be installed/upgraded:\n\n"); // Iterator<Package> i = finalListToInstall.iterator(); // while (i.hasNext()) { // System.out.println("\t" + i.next()); // } // System.out.print("\nOK to proceed [y/n]? > "); // String response = queryUser(); // // if (response != null && (response.equalsIgnoreCase("n") || // response.equalsIgnoreCase("no"))) { // return; // bail out here // } // } // // // OK, now we can download and install everything // // // First install the final list of dependencies // installPackages(finalListToInstall, System.out); // // // Now install the package itself // installPackageFromRepository(packageName, version, System.out); // // } else { // // just install this package without checking/downloading dependencies etc. // installPackageFromRepository(packageName, version, System.out); // } // } // // private static void listPackages(String arg) throws Exception { // List<Package> packageList = null; // useCacheOrOnlineRepository(); // // if (arg.equalsIgnoreCase("all")) { // packageList = PACKAGE_MANAGER.getAllPackages(); // } else if (arg.equals("installed")) { // packageList = PACKAGE_MANAGER.getInstalledPackages(); // } else if (arg.equals("available")) { // packageList = PACKAGE_MANAGER.getAvailablePackages(); // } else { // System.err.println("[WekaPackageManager] Unknown argument " + arg); // printUsage(); // //System.exit(1); // return; // } // // StringBuffer result = new StringBuffer(); // result.append("Installed\tRepository\tPackage\n"); // result.append("=========\t==========\t=======\n"); // // Iterator<Package> i = packageList.iterator(); // while (i.hasNext()) { // Package p = i.next(); // String installedV = "----- "; // String repositoryV = "----- "; // if (p.isInstalled()) { // Package installedP = getInstalledPackageInfo(p.getName()); // installedV = installedP.getPackageMetaDataElement("Version").toString() + " "; // try { // Package repP = getRepositoryPackageInfo(p.getName()); // repositoryV = repP.getPackageMetaDataElement("Version").toString() + " "; // } catch (Exception ex) { // // not at the repository // } // } else { // repositoryV = p.getPackageMetaDataElement("Version").toString() + " "; // } // String title = p.getPackageMetaDataElement("Title").toString(); // result.append(installedV + "\t" + repositoryV + "\t" // + p.getName() + ": " + title + "\n"); // } // // System.out.println(result.toString()); // } // // private static void printUsage() { // System.out.println("Usage: weka.core.WekaPackageManager [option]"); // System.out.println("Options:\n" // + "\t-list-packages <all | installed | available>\n" // + "\t-package-info <repository | installed | archive> " // + "<packageName | packageZip>\n\t-install-package <packageName | packageZip | URL> [version]\n" // + "\t-uninstall-package packageName\n" // + "\t-refresh-cache"); // } // // public static void main(String[] args) { // weka.core.logging.Logger.log(weka.core.logging.Logger.Level.INFO, "Logging started"); // try { // // establishCacheIfNeeded(System.out); // checkForNewPackages(System.out); // // if (args.length == 0 || args[0].equalsIgnoreCase("-h") || // args[0].equalsIgnoreCase("-help")) { // printUsage(); // //System.exit(1); // return; // } // // if (args[0].equals("-package-info")) { // if (args.length < 3) { // printUsage(); // return; // //System.exit(1); // } // if (args[1].equals("archive")) { // printPackageArchiveInfo(args[2]); // } else if (args[1].equals("installed")) { // printInstalledPackageInfo(args[2]); // } else if (args[1].equals("repository")) { // String version = "Latest"; // if (args.length == 4) { // version = args[3]; // } // try { // printRepositoryPackageInfo(args[2], version); // } catch (Exception ex) { // // problem with getting info on package from repository? // // Must not be an "official" repository package // System.out.println("[WekaPackageManager] Nothing known about package " // + args[2] + " at the repository!"); // } // } else { // System.err.println("[WekaPackageManager] Unknown argument " + args[2]); // printUsage(); // return; // //System.exit(1); // } // } else if (args[0].equals("-install-package")) { // String targetLowerCase = args[1].toLowerCase(); // if (targetLowerCase.startsWith("http://") || // targetLowerCase.startsWith("https://")) { // URL packageURL = new URL(args[1]); // installPackageFromURL(packageURL, System.out); // } else if (targetLowerCase.endsWith(".zip")) { // installPackageFromArchive(args[1], System.out); // } else { // // assume a named package at the central repository // String version = "Latest"; // if (args.length == 3) { // version = args[2]; // } // installPackageFromRepository(args[1], version, false); // } // } else if (args[0].equals("-uninstall-package")) { // if (args.length < 2) { // printUsage(); // return; // //System.exit(1); // } // boolean force = false; // // if (args.length == 3) { // if (args[2].equals("-force")) { // force = true; // } // } // // removeInstalledPackage(args[1], force, System.out); // //System.exit(0); // return; // } else if (args[0].equals("-list-packages")) { // if (args.length < 2) { // printUsage(); // //System.exit(1); // return; // } // listPackages(args[1]); // // } else if (args[0].equals("-refresh-cache")) { // refreshCache(System.out); // } else { // System.err.println("Unknown option: " + args[0]); // printUsage(); // } // } catch (Exception ex) { // ex.printStackTrace(); // } // } }