/* * 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. */ /* * RepositoryIndexGenerator.java * Copyright (C) 2000-2010 University of Waikato, Hamilton, New Zealand * */ package weka.core; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.Iterator; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.TreeMap; /** * Class for generating html index files and supporting text files * for a Weka package meta data repository. To Run<br><br> * * <code>java weka.core.RepositoryIndexGenerator <path to repository></code> * * @author Mark Hall (mhall{[at]}pentaho{[dot]}com) * @version $Revision: 6973 $ */ public class RepositoryIndexGenerator { public static String HEADER = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n" + "<html>\n<head>\n<title>Waikato Environment for Knowledge Analysis (WEKA)</title>\n" + "<!-- CSS Stylesheet -->\n<style>body\n{\nbackground: #ededed;\ncolor: #666666;\n" + "font: 14px Tahoma, Helvetica, sans-serif;;\nmargin: 5px 10px 5px 10px;\npadding: 0px;\n" + "}\n</style>\n\n</head>\n<body bgcolor=\"#ededed\" text=\"#666666\">\n"; public static String BIRD_IMAGE1 = "<img src=\"Title-Bird-Header.gif\">\n"; public static String BIRD_IMAGE2 = "<img src=\"../Title-Bird-Header.gif\">\n"; public static String PENTAHO_IMAGE1 = "<img src=\"pentaho_logo_rgb_sm.png\">\n\n"; public static String PENTAHO_IMAGE2 = "<img src=\"../pentaho_logo_rgb_sm.png\">\n\n"; private static int[] parseVersion(String version) { int major = 0; int minor = 0; int revision = 0; int[] majMinRev = new int[3]; try { String tmpStr = version; tmpStr = tmpStr.replace('-', '.'); if (tmpStr.indexOf(".") > -1) { major = Integer.parseInt(tmpStr.substring(0, tmpStr.indexOf("."))); tmpStr = tmpStr.substring(tmpStr.indexOf(".") + 1); if (tmpStr.indexOf(".") > -1) { minor = Integer.parseInt(tmpStr.substring(0, tmpStr.indexOf("."))); tmpStr = tmpStr.substring(tmpStr.indexOf(".") + 1); if (!tmpStr.equals("")) { revision = Integer.parseInt(tmpStr); } else { revision = 0; } } else { if (!tmpStr.equals("")) { minor = Integer.parseInt(tmpStr); } else { minor = 0; } } } else { if (!tmpStr.equals("")) { major = Integer.parseInt(tmpStr); } else { major = 0; } } } catch (Exception e) { e.printStackTrace(); major = -1; minor = -1; revision = -1; } finally { majMinRev[0] = major; majMinRev[1] = minor; majMinRev[2] = revision; } return majMinRev; } private static String cleansePropertyValue(String propVal) { propVal = propVal.replace("<", "<"); propVal = propVal.replace(">", ">"); propVal = propVal.replace("@", "{[at]}"); propVal = propVal.replace("\n", "<br/>"); return propVal; } protected static int compare(String version1, String version2) { // parse both of the versions int[] majMinRev1 = parseVersion(version1); int[] majMinRev2 = parseVersion(version2); int result; if (majMinRev1[0] < majMinRev2[0]) { result = -1; } else if (majMinRev1[0] == majMinRev2[0]) { if (majMinRev1[1] < majMinRev2[1]) { result = -1; } else if (majMinRev1[1] == majMinRev2[1]) { if (majMinRev1[2] < majMinRev2[2]) { result = -1; } else if (majMinRev1[2] == majMinRev2[2]) { result = 0; } else { result = 1; } } else { result = 1; } } else { result = 1; } return result; } private static String[] processPackage(File packageDirectory) throws Exception { System.err.println("Processing " + packageDirectory); File[] contents = packageDirectory.listFiles(); File latest = null; ArrayList<File> propsFiles = new ArrayList<File>(); StringBuffer versionsTextBuffer = new StringBuffer(); for (int i = 0; i < contents.length; i++) { if (contents[i].isFile() && contents[i].getName().endsWith(".props")) { propsFiles.add(contents[i]); if (contents[i].getName().equals("Latest.props")) { latest = contents[i]; } /*else { String versionNumber = contents[i].getName().substring(0, contents[i].getName().indexOf(".props")); versionsTextBuffer.append(versionNumber + "\n"); } */ } } File[] sortedPropsFiles = propsFiles.toArray(new File[0]); Arrays.sort(sortedPropsFiles, new Comparator<File>() { public int compare (File first, File second) { String firstV = first.getName().substring(0, first.getName().indexOf(".props")); String secondV = second.getName().substring(0, second.getName().indexOf(".props")); if (firstV.equalsIgnoreCase("Latest")) { return -1; } else if (secondV.equalsIgnoreCase("Latest")) { return 1; } return -RepositoryIndexGenerator.compare(firstV, secondV); } }); StringBuffer indexBuff = new StringBuffer(); indexBuff.append(HEADER +"\n\n"); //indexBuff.append(HEADER + BIRD_IMAGE2); //indexBuff.append(PENTAHO_IMAGE2); Properties latestProps = new Properties(); latestProps.load(new BufferedReader(new FileReader(latest))); String packageName = latestProps.getProperty("PackageName") + ": "; String packageTitle = latestProps.getProperty("Title"); String packageCategory = latestProps.getProperty("Category"); if (packageCategory == null) { packageCategory = ""; } indexBuff.append("<h2>" + packageName + packageTitle + "</h2>\n\n"); String author = latestProps.getProperty("Author"); author = cleansePropertyValue(author); String URL = latestProps.getProperty("URL"); if (URL != null) { URL = cleansePropertyValue(URL); } String maintainer = latestProps.getProperty("Maintainer"); maintainer = cleansePropertyValue(maintainer); indexBuff.append("\n<table>\n"); if (URL != null && URL.length() > 0) { indexBuff.append("<tr><td valign=top>"+ "URL" + ":</td><td width=50></td>"); URL = "<a href=\"" + URL +"\">" + URL + "</a>"; indexBuff.append("<td>" + URL + "</td></tr>\n"); } indexBuff.append("<tr><td valign=top>"+ "Author" + ":</td><td width=50></td>"); indexBuff.append("<td>" + author + "</td></tr>\n"); indexBuff.append("<tr><td valign=top>"+ "Maintainer" + ":</td><td width=50></td>"); indexBuff.append("<td>" + maintainer + "</td></tr>\n"); indexBuff.append("</table>\n<p>\n"); String description = latestProps.getProperty("Description"); indexBuff.append("<p>" + description.replace("\n", "<br/>") + "</p>\n\n"); indexBuff.append("<p>All available versions:<br>\n"); for (int i = 0; i < sortedPropsFiles.length; i++) { if (i > 0) { String versionNumber = sortedPropsFiles[i].getName().substring(0, sortedPropsFiles[i].getName().indexOf(".props")); versionsTextBuffer.append(versionNumber + "\n"); System.err.println(versionNumber); } String name = sortedPropsFiles[i].getName(); name = name.substring(0, name.indexOf(".props")); indexBuff.append("<a href=\"" + name + ".html" + "\">" + name + "</a><br>\n"); StringBuffer version = new StringBuffer(); version.append(HEADER + "\n\n"); //version.append(HEADER + BIRD_IMAGE2); // version.append(PENTAHO_IMAGE2); version.append("<table summary=\"Package " + packageName + " summary\">\n"); Properties versionProps = new Properties(); versionProps.load(new BufferedReader(new FileReader(sortedPropsFiles[i]))); Set<Object> keys = versionProps.keySet(); String[] sortedKeys = keys.toArray(new String[0]); Arrays.sort(sortedKeys); // Iterator<Object> keyI = keys.iterator(); //while (keyI.hasNext()) { for (String key : sortedKeys) { // String key = (String)keyI.next(); if (key.equalsIgnoreCase("PackageName") || key.equalsIgnoreCase("Title") || /*key.equalsIgnoreCase("Description") || */ key.equalsIgnoreCase("DoNotLoadIfFileNotPresentMessage") || key.equalsIgnoreCase("DoNotLoadIfClassNotPresentMessage")) { } else { version.append("<tr><td valign=top>"+ key + ":</td><td width=50></td>"); String propValue = versionProps.getProperty(key); if (!key.equalsIgnoreCase("Description")) { propValue = propValue.replace("<", "<"); propValue = propValue.replace(">", ">"); propValue = propValue.replace("@", "{[at]}"); propValue = propValue.replace("\n", "<br/>"); } /*if (key.equals("Author") || key.equals("Maintainer")) { propValue = propValue.replace(".", "{[dot]}"); } */ if (key.equals("PackageURL") || key.equals("URL")) { propValue = "<a href=\"" + propValue +"\">" + propValue + "</a>"; } version.append("<td>" + propValue + "</td></tr>\n"); } } version.append("</table>\n</body>\n</html>\n"); String versionHTMLFileName = packageDirectory.getAbsolutePath() + File.separator + name + ".html"; BufferedWriter br = new BufferedWriter(new FileWriter(versionHTMLFileName)); br.write(version.toString()); br.flush(); br.close(); } indexBuff.append("</body>\n</html>\n"); String packageIndexName = packageDirectory.getAbsolutePath() + File.separator + "index.html"; BufferedWriter br = new BufferedWriter(new FileWriter(packageIndexName)); br.write(indexBuff.toString()); br.flush(); br.close(); // write the versions file to the directory String packageVersionsName = packageDirectory.getAbsolutePath() + File.separator + "versions.txt"; br = new BufferedWriter(new FileWriter(packageVersionsName)); br.write(versionsTextBuffer.toString()); br.flush(); br.close(); // return indexBuff.toString(); String[] returnInfo = new String[2]; returnInfo[0] = packageTitle; returnInfo[1] = packageCategory; return returnInfo; } private static void writeMainIndex(Map<String, String[]> packages, File repositoryHome) throws Exception { StringBuffer indexBuf = new StringBuffer(); StringBuffer packageList = new StringBuffer(); indexBuf.append(HEADER + BIRD_IMAGE1); indexBuf.append(PENTAHO_IMAGE1); indexBuf.append("<h1>WEKA Packages </h1>\n\n"); indexBuf.append(/*"<h3>Download WekaLite</h3>\n<a href=\"wekaLite.jar\">wekaLite.jar</a>" + */ "<p><b>IMPORTANT: make sure there are no old versions of Weka (<3.7.2) in " + "your CLASSPATH before starting Weka</b>\n\n"); indexBuf.append("<h3>Installation of Packages</h3>\n"); indexBuf.append("A GUI package manager is available from the \"Tools\" menu of" + " the GUIChooser<br><br><code>java -jar weka.jar</code><p>\n\n"); indexBuf.append("For a command line package manager type" + ":<br><br<code>java weka.core.WekaPackageManager -h" + "</code><br><br>\n"); indexBuf.append("<hr/>\n"); indexBuf.append("<h3>Running packaged algorithms from the command line</h3>" + "<code>java weka.Run [algorithm name]</code><p>" + "Substring matching is also supported. E.g. try:<br><br>" + "<code>java weka.Run Bayes</code><hr/>"); Set<String> names = packages.keySet(); indexBuf.append("<h3>Available Packages (" + packages.keySet().size() +")</h3>\n\n"); indexBuf.append("<table>\n"); Iterator<String> i = names.iterator(); while (i.hasNext()) { String packageName = i.next(); String[] info = packages.get(packageName); String packageTitle = info[0]; String packageCategory = info[1]; String href = "<a href=\"./" + packageName + "/index.html\">" + packageName + "</a>"; indexBuf.append("<tr valign=\"top\">\n"); indexBuf.append("<td>" + href + "</td><td width=50></td><td>" + packageCategory + "</td><td width=50></td><td>" + packageTitle + "</td></tr>\n"); // append to the package list packageList.append(packageName + "\n"); } indexBuf.append("</table>\n<hr/>\n</body></html>\n"); String indexName = repositoryHome.getAbsolutePath() + File.separator + "index.html"; BufferedWriter br = new BufferedWriter(new FileWriter(indexName)); br.write(indexBuf.toString()); br.flush(); br.close(); String packageListName = repositoryHome.getAbsolutePath() + File.separator + "packageList.txt"; br = new BufferedWriter(new FileWriter(packageListName)); br.write(packageList.toString()); br.flush(); br.close(); String numPackagesName = repositoryHome.getAbsolutePath() + File.separator + "numPackages.txt"; br = new BufferedWriter(new FileWriter(numPackagesName)); br.write(packages.keySet().size() + "\n"); br.flush(); br.close(); } /** * Main method for running the RepositoryIndexGenerator * * @param args first argument needs to be the path the the * repository. */ public static void main(String[] args) { try { if (args.length < 1) { System.err.println("Usage:\n\n\tRepositoryIndexGenerator <path to repository>"); System.exit(1); } StringBuffer mainIndex = new StringBuffer(); File repositoryHome = new File(args[0]); TreeMap<String, String[]> packages = new TreeMap<String, String[]>(); // ArrayList<File> packages = new ArrayList<File>(); File[] contents = repositoryHome.listFiles(); for (int i = 0; i < contents.length; i++) { if (contents[i].isDirectory()) { // packages.add(contents[i]); // process this package and create its index String[] packageInfo = processPackage(contents[i]); packages.put(contents[i].getName(), packageInfo); } } // write the main index file writeMainIndex(packages, repositoryHome); } catch (Exception ex) { ex.printStackTrace(); } } }