Package uk.ac.osswatch.simal

Source Code of uk.ac.osswatch.simal.Simal

package uk.ac.osswatch.simal;

/*
* Copyright 2007 University of Oxford
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Iterator;
import java.util.Set;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
import org.apache.log4j.PropertyConfigurator;
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;

import uk.ac.osswatch.simal.importData.Ohloh;
import uk.ac.osswatch.simal.importData.PTSWImport;
import uk.ac.osswatch.simal.model.IPerson;
import uk.ac.osswatch.simal.model.IProject;
import uk.ac.osswatch.simal.model.IResource;
import uk.ac.osswatch.simal.rdf.ISimalRepository;
import uk.ac.osswatch.simal.rdf.SimalException;
import uk.ac.osswatch.simal.rdf.SimalRepositoryException;

/**
* The Command Line Interface for a Simal repository.
*
*/
public class Simal {
  private static final Logger logger = LoggerFactory.getLogger(Simal.class);
  private static final String CMD_BACKUP = "backup";
  private static ISimalRepository repository;

  public Simal() throws SimalRepositoryException {
  }

  /**
   * @param args
   * @throws SimalRepositoryException
   * @throws ParseException
   */
  @SuppressWarnings( { "unchecked", "static-access" })
  public static void main(String[] args) throws SimalRepositoryException {
    try {
      repository = SimalRepositoryFactory.getInstance();
    } catch (SimalRepositoryException e) {
      throw new IllegalStateException("Unable to create repository", e);
    }

    Options opts = new Options();

    Option help = new Option("h", "help", false,
        "Print help for the Simal command line interface and exit");
    opts.addOption(help);

    Option version = new Option("v", "version", false,
        "Print the version number of Simal and exit");
    opts.addOption(version);

    Option directory = new Option("d", "dir", true,
        "The directory in which the persistent data store resides");
    opts.addOption(directory);

    Option properties = new Option("p", "properties", true,
        "The properties file to use");
    opts.addOption(properties);

    Option nameFilters = new Option("n", "nameFilter", true,
        "A regex for filtering entities based on their names");
    opts.addOption(nameFilters);

    Option summary = new Option("s", "summary", false,
        "When displaying resource information only display summary details.");
    opts.addOption(summary);

    Option filename = new Option("f", "filename", true,
        "The filename to use for this command.");
    opts.addOption(filename);

    Option test = new Option(
        "t",
        "test",
        false,
        "Start the repository in test mode, the repository is populated with some test data, all changes are lost when the CLI commands have been executed");
    opts.addOption(test);

    Option property = OptionBuilder.withArgName("property=value").hasArg()
        .withValueSeparator().withDescription("use value for given property")
        .create("D");
    opts.addOption(property);

    PosixParser parser = new PosixParser();
    CommandLine cl = null;
    try {
      cl = parser.parse(opts, args);
    } catch (ParseException e) {
      logger.error(e.getMessage());
      logger
          .error("Please use the \"--help\" option to see a list of valid commands and options");
      System.exit(1);
    }

    PropertyConfigurator
        .configure(Simal.class.getResource("/log4j.properties"));

    if (cl.hasOption('h')) {
      printHelp(opts);
    } else {
      Iterator<Option> options = cl.iterator();
      Option opt;
      while (options.hasNext()) {
        opt = options.next();
        if (opt.equals(test)) {
          try {
            logger.info("Setting repository to test mode");
            repository.setIsTest(true);
          } catch (SimalRepositoryException e) {
            logger.error("Weird, that shouldn't happen...", e);
            System.exit(1);
          }
        }
      }

      String propsPath = cl.getOptionValue("properties");
      if (propsPath != null && propsPath.length() > 0) {
        File file;
        if (!(propsPath.indexOf(":") < 0)
            || propsPath.startsWith(File.separator)) {
          file = new File(propsPath);
        } else {
          String workingDir = System.getProperty("user.dir");
          file = new File(workingDir + File.separator + propsPath);
        }
        logger.info("using properties file " + file.toString());
        SimalProperties.setLocalPropertiesFile(file);
      }

      if (cl.hasOption('v')) {
        printVersion();
      }

      String dir = cl.getOptionValue("dir");
      logger.info("Setting database directory to " + dir);

      logger.info("Initialising repository...");
      initRepository(dir);
      logger.info("Executing commands...");

      executeCommands(cl);
    }
  }

  private static void executeCommands(CommandLine cl) {
    String[] cmds = cl.getArgs();
    String cmd;
    for (int i = 0; i < cmds.length; i++) {
      cmd = cmds[i];
      if (cmd.equals("addxml")) {
        addXMLFile((String) cmds[i + 1]);
        i++;
      } else if (cmd.equals("addxmldir")) {
        try {
          repository.addXMLDirectory((String) cmds[i + 1]);
        } catch (SimalRepositoryException e) {
          logger.error("Error adding data - adborting", e);
          System.exit(1);
        }
        i++;
      } else if (cmd.equals("getPeople")) {
        try {
          getPeople(cl);
        } catch (SimalRepositoryException e) {
          logger.error("Unable to get projects: " + e.getMessage() + "\n",
              e);
          System.exit(1);
        }
        i++;
      } else if (cmd.equals("getProjects")) {
        try {
          getProjects(cl);
        } catch (SimalRepositoryException e) {
          logger.error("Unable to get projects: " + e.getMessage() + "\n",
              e);
          System.exit(1);
        }
        i++;
      } else if (cmd.equals("write")) {
        write((String) cmds[i + 1], cl);
        i++;
      } else if (cmd.equals("importPTSW")) {
        try {
          importPTSW();
        } catch (SimalException e) {
          logger.error("Unable to Import from PTSW: " + e.getMessage() + "\n",
              e);
          System.exit(1);
        }
        i++;
      } else if (cmd.equals("importOhloh")) {
        try {
          if (cl.hasOption('f')) {
              String filename = cl.getOptionValue('f');
        File file = new File(filename);
              importOhloh(file);
          } else {
          importOhloh((String) cmds[i + 1]);
          }
            i++;
        } catch (SimalException e) {
              logger.error("Unable to Import from Ohloh: " + e.getMessage() + "\n",
                        e);
            System.exit(1);
          } catch (IOException e) {
            logger.error("Unable to Import from Ohloh: " + e.getMessage() + "\n",
                    e);
            System.exit(1);
      }
      } else if (cmd.equals(CMD_BACKUP)) {
        i++;
        backup(cmds, i);
      } else {
        logger.info("Ignoring unrecognised command: " + cmd);
      }
    }
  }

  /**
   * Get the people indicated in the options.
   * (e.g. '-nameFilter foo' will get all people with 'foo' in their name).
   * The people data will be dumped to the log in the format
   * specified by the command line options.
   * @param cl
   * @throws SimalRepositoryException
   */
  private static void getPeople(CommandLine cl) throws SimalRepositoryException {
    if (cl.hasOption('n')) {
      String filter = cl.getOptionValue('n');
      Set<IPerson> people = SimalRepositoryFactory.getPersonService().filterByName(filter);
      if (people == null || people.size() == 0) {
        logger.info("No projects match the regular expression '" + filter + "'");
      } else {
        Iterator<IPerson> itr = people.iterator();
        while(itr.hasNext()) {
          IPerson person = itr.next();
          dump(person, cl);
          logger.info("\n\n============================================\n============================================\n\n");
        }
      }
    }
  }

  /**
   * Get the projects indicated in the options.
   * (e.g. '-nameFilter foo' will get all projects with 'foo' in their name).
   * The project data will be dumped to the log in the format
   * specified by the command line options.
   * @param cl
   * @throws SimalRepositoryException
   */
  private static void getProjects(CommandLine cl) throws SimalRepositoryException {
    String filter;
    if (cl.hasOption('n')) {
      filter = cl.getOptionValue('n');
    } else {
      filter = ".*"; // if no filter, return all projects.
    }
     
    Set<IProject> projects = SimalRepositoryFactory.getProjectService().filterByName(filter);
    if (projects == null || projects.size() == 0) {
      logger.info("No projects match the regular expression '" + filter + "'");
    } else {
      Iterator<IProject> itr = projects.iterator();
      while(itr.hasNext()) {
        IProject project = itr.next();
        dump(project, cl);
        logger.info("\n\n============================================\n============================================\n\n");
      }
    }
  }

  /**
   * Dump the project details as specified in the command line options.
   * The default format is XML.
   * @param project
   * @param cl
   * @throws SimalRepositoryException
   */
  private static void dump(IResource resource, CommandLine cl) throws SimalRepositoryException {
    if (cl.hasOption('s')) {
      StringBuilder msg = new StringBuilder(resource.getLabel());
      msg.append(" - ");
      msg.append(resource.getURI());
      logger.info(msg.toString());
    } else {
      logger.info(resource.toXML());
    }
  }

  /**
   * Write a backup of the repository to a file defined in the next position of
   * the command string.
   *
   * @param cmds -
   *          the array of commands
   * @param fileIndex -
   *          the index of the filename
   */
  private static void backup(String[] cmds, int fileIndex) {
    if (fileIndex == cmds.length) {
      logger.error("You must provide a filename for the backup file");
      System.exit(1);
    }
    String file = (String) cmds[fileIndex];
    if (file == null || file.equals("")) {
      logger.error("You must provide a filename for the backup file");
      System.exit(1);
    }
    File backupFile = new File(file);
    if (backupFile.exists()) {
      logger.error("The file already exists, you must provide a new filename");
      System.exit(1);
    }
    try {
      if (backupFile.createNewFile()) {
        FileWriter writer = new FileWriter(backupFile);
        getRepository().writeBackup(writer);
        writer.close();
        logger.info("Backup file written to " + backupFile.getAbsolutePath());
      }
    } catch (IOException e) {
      logger.error("Unable to create the backup file: " + e.getMessage(), e);
      System.exit(1);
    }
  }

  /**
   * Import a project from Ohloh
   *
   * @param id
   */
  private static void importOhloh(String id) throws SimalException {
    Ohloh ohloh = new Ohloh();
    ohloh.addProjectToSimal(id);
  }

  /**
   * Import multiple projects from Ohloh. Each project is listed in the file supplied.
   *
   * @param file
   * @throws IOException
   */
  private static void importOhloh(File file) throws SimalException, IOException {
    Ohloh ohloh = new Ohloh();
    ohloh.importProjects(file);
  }

  /**
   * Import all the documents updated since the last time we updated from PTSW.
   *
   * @throws SimalException
   */
  private static void importPTSW() throws SimalException {
    PTSWImport importer = new PTSWImport();
    Document pings = importer.getLatestPingsAsRDF();
    OutputFormat format = new OutputFormat(pings);
    StringWriter writer = new StringWriter();
    XMLSerializer serial = new XMLSerializer(writer, format);
    try {
      serial.serialize(pings);
    } catch (IOException e) {
      throw new SimalException("Unable to serialize PTSW response");
    }
    logger.info("Updated DOAP documents:\n");
    logger.info(writer.toString());

    File tmpFile = new File(System.getProperty("java.io.tmpdir")
        + File.separator + "PTSWExport.xml");
    FileWriter fw = null;
    try {
      fw = new FileWriter(tmpFile);
      fw.write(writer.toString());
    } catch (IOException e) {
      throw new SimalException(
          "Unable to write PTSW export file to temporary space");
    } finally {
      if (fw != null) {
        try {
          fw.close();
        } catch (IOException e) {
          throw new RuntimeException("Attempt to close a file writer failed", e);
        }
      }
    }

    try {
      repository.addProject(tmpFile.toURI().toURL(), tmpFile.toURI().toURL()
          .toExternalForm());
    } catch (MalformedURLException e) {
      throw new SimalException("Unable to add projects from PTSW Export", e);
    }
  }

  /**
   * Write a resource in the format indicated in the command line options.
   * Default s XML.
   * @param cl
   *
   * @param qname
   */
  private static void write(final String uri, CommandLine cl) {
    logger.info("Writing XML for " + uri);
    try {
      IResource resource = repository.getResource(uri);
      dump(resource, cl);
    } catch (SimalRepositoryException e) {
      logger.error("Unable to write XML to standard out");
      System.exit(1);
    }
  }

  /**
   * Add an RDF/XML file to the repository.
   */
  private static void addXMLFile(final String filenameOrURL) {
    logger.info("Adding XML from " + filenameOrURL);

    try {
      URL fileURL;
      if (!filenameOrURL.contains(":/")) {
        if (filenameOrURL.startsWith("/") || filenameOrURL.indexOf(':') == 1) {
          fileURL = new File(filenameOrURL).toURI().toURL();
        } else {
          fileURL = new File(System.getProperty("user.dir") + File.separator
              + filenameOrURL).toURI().toURL();
        }
      } else {
        fileURL = new URL(filenameOrURL);
      }
      try {
        repository.addProject(fileURL, "");
      } catch (SimalException e) {
        logger.error("Unable to add an RDF/XML document {}", fileURL
            .toExternalForm(), e);
        System.exit(1);
      }
    } catch (MalformedURLException e) {
      logger.error("The URL specified in --addxml  is not a valid URL.");
      System.exit(1);
    }
    logger.info("DOAP data succesffuly added via the CLI.");
    System.out.println("DOAP data succesfully added.");
  }

  private static void initRepository(String dir) {
    try {
      if (dir == null || dir.equals("")) {
        repository.initialise();
      } else {
        repository.initialise(dir);
      }
    } catch (SimalRepositoryException e) {
      logger.error("Unable to start repository: {}", e.getMessage());
      e.printStackTrace();
    }
  }

  private static void printVersion() {
    String version;
    try {
      version = SimalProperties
          .getProperty(SimalProperties.PROPERTY_SIMAL_VERSION);
    } catch (SimalRepositoryException e) {
      version = "ERROR: unable to read properties file";
    }
    logger.info("Simal version   : " + version);
    logger.info("Java version    : " + System.getProperty("java.version"));
    logger.info("Java vendor     : " + System.getProperty("java.vendor"));
    logger.info("OS              : " + System.getProperty("os.name"));
    logger.info("OS Architecture : " + System.getProperty("os.arch"));
    System.exit(0);
  }

  private static void printHelp(Options opts) {
    HelpFormatter f = new HelpFormatter();

    String header = "Options";

    StringBuffer commandSummary = new StringBuffer("\n");
    commandSummary.append("Command      Argument(s)   Description\n\n");
    commandSummary.append("=======      ===========   ===========\n\n");
    commandSummary
        .append("addxml       FILE_OR_URL   add an RDF/XML file to the repository.\n\n");
    commandSummary
        .append("addxmldir    DIRECTORY     add all RDF/XML files found in a directory.\n\n");
    commandSummary
        .append("getPeople                  get all people, or those indicated in the options.\n\n");
    commandSummary
        .append("getProjects                get all projects, or those indicated in the options.\n\n");
    commandSummary
        .append("importOhloh  FILE_OR_ID    import a project from Ohloh with a given ID.\n\n");
    commandSummary
        .append("importPTSW                 Import all recently updated DOAP files from PTSW\n\n");
    commandSummary
        .append("write        URI           write the entity with the given URI in the format indicated in the options (default is XML).\n\n");
    commandSummary
        .append(CMD_BACKUP
            + "       FILE          write a backup of the whole repository to FILE.\n\n");

    f.printHelp("simal [options] [command [args] [command [args]] ... ]",
        header, opts, commandSummary.toString(), false);
  }

  public static ISimalRepository getRepository() {
    return repository;
  }

}
TOP

Related Classes of uk.ac.osswatch.simal.Simal

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.