Package Galaxy.Toolbox

Source Code of Galaxy.Toolbox.GalaxyToolDatabase$Entry

package Galaxy.Toolbox;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Reader;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.ConversionException;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.UnknownFieldException;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.StreamException;
import com.thoughtworks.xstream.io.xml.StaxDriver;

import CLInterface.ConverterConfig;
import CLInterface.Printer;
import Core.Pair;
import Core.Triple;
import FileOps.XStream.XStreamWrapper;
import Galaxy.Tree.Tool.Tool;
import Specification.GalaxySpecification;
/***
* The GalaxyToolDatabase loads the Galaxy Tools given the root directory
* of a galaxy installation. It supports loading existing tools, adding
* new tools, and writing the modified tool library to a directory.
*
* @author viper
*
*/
public class GalaxyToolDatabase {
  /***
   * INDEX_NAME: name of tool index file.
   */
  final String INDEX_NAME = "tool_conf.xml";
  /***
   * TOOL_DIRECTORY: name of directory where tools are stored.
   */
  final String TOOL_DIRECTORY = "tools";
  /***
   * toolDB: Stores all the tool objects. The key value of the map
   * is the tool id. The first string in the triple is the relative path to the tool.
   * The second string in the triple is the package name of the tool, and the
   * Toolt object in the tripleis the loaded Tool object. This is null by default
   * and gets filled in if the tool is requested.
   */
  public Map<String, Triple<String,String, Tool>> toolDB;
  /***
   * toolIndexParser: This is an xml parser for parsing the tool index file.
   */
  XStreamWrapper<Toolbox> toolIndexParser;
  /***
   * toolIndex: This is the object representation of the tool index.
   */
  Toolbox toolIndex;
 
  /***
   * Get the list of ids contained in the tool database.
   * @return A set of tool ids.
   */
  public Set<String> getTools(){
    return toolDB.keySet();
  }
  /***
   * The Toolbox object contains all the information inside the
   * toolbox tag set. This includes a list of sections.
   * @author viper
   *
   */
  static class Toolbox{
    List<Section> sections;
    public String toString(){
      return sections.toString();
    }
   
  }
  /***
   * This corresponds to a section tag set. A section has a name
   * (the package name), and an id, as well as a list of entries.
   * @author viper
   *
   */
  static class Section{
    List<Entry> entries;
    String name;
    String id;
    public String toString(){
      return "<name:"+name+" id:"+id+" entries:"
          +entries.toString()+">";
    }
  }
  /***
   * The entry class is a dummy class that is extended
   * by tags contained within the section tag set.
   * @author viper
   *
   */
  static class Entry{}
  /***
   * A ToolEntry corresponds to the information contained in the
   * tool tag set. Each ToolEntry has a path.
   * @author viper
   *
   */
  static class ToolEntry extends Entry{
    String path;
    public String toString(){
      return "[T] "+path;
    }
  }
  /***
   * A LabelEntry corresponds to information inside the label tagset.
   * This is only used inside the parsing step. Contains the string label.
   * @author viper
   *
   */
  static class LabelEntry extends Entry{
    String label;
    public String toString(){
      return "[L] "+ label;
    }
  }
  /***
   *
   * @param id The id of the tool to get a relative path for.
   * @param pkg The package the tool is contained in
   * @return returns the relative path package/id.xml
   */
  private String ToolPairToRelativePath(String id, String pkg){
    return pkg+ "/"+ id+".xml";
  }
  /***
   * Turn a relative path into an absolute path.
   * directory.
   * @param path relative to the root of the tool/ directory
   * @return absolute path, using the galaxy input directory as the galaxy directory.
   */
  public String relativePathToInputToolPath(String relativePath){
    String toolPath;
    toolPath = (String) ConverterConfig.GALAXY_INPUT_DIR;
    toolPath += TOOL_DIRECTORY + "/";
    toolPath += relativePath;
    return toolPath;
  }
  /***
   *
   * @param path relative to the root of the tool directory.
   * @return absolute path, using the galaxy output directory as the galaxy directory.
   */
  private String relativePathToOutputToolPath(String relativePath){
    String toolPath;
    toolPath = (String) ConverterConfig.GALAXY_OUTPUT_DIR;
    toolPath += TOOL_DIRECTORY + "/";
    toolPath += relativePath;
    return toolPath;
  }
  /**
   * Visits all the objects in the parsed tool index tree and populates the database
   * object entries in the database.
   * @author viper
   *
   */
  class ToolIndexVisitor{
    /**
     * Scrapes the tool's XML file to find the id of the tool. The XML file is not
     * fully parsed in this operation.
     * @param relative path of the tool from the root of the tool directory.
     * @return the id of the tool that was scraped from the file.
     */
    private String getToolIdFromToolXML(String relativePath){
      String toolPath;
      XStream xstream;
      BufferedReader reader;
      toolPath = relativePathToInputToolPath(relativePath);
     
      xstream = new XStream(new StaxDriver());
      try {
        reader = new BufferedReader(new FileReader(toolPath));
        StaxDriver xmlParser = new StaxDriver();
        HierarchicalStreamReader xmlPeeker= xmlParser.createReader(reader);
        String tool_id= xmlPeeker.getAttribute("id");
        reader.close();
        return tool_id;
      } catch(StreamException e){
        System.err.println("Error loading "+ relativePath);
        System.err.println(e.getCause().toString());
      }
      catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        System.err.println("Error loading "+ relativePath);
        System.err.println(e.getCause());
      } catch (IOException e) {
        // TODO Auto-generated catch block
        System.err.println("Error loading "+ relativePath);
        System.err.println(e.getCause());
      }
      return "";
    }
   
    /***
     * Adds a new tool to the tool database using infomation
     * contained in the ToolEntry object and the package string.
     *
     * @param toolentry The toolEntry to visit
     * @param pkg the name of the package the tool iscontained in.
     */
    public void visit(ToolEntry toolentry, String pkg){
     
      String tool_id = getToolIdFromToolXML(toolentry.path);
      if(tool_id.equals("") == false)
        toolDB.put(tool_id, new Triple<String,String, Tool>(
              toolentry.path, pkg,
            null
            ));
     
    }
    /***
     * Visits all the entries inside a section, calling the appropriate
     *  visit function for each visit. The section id is used as the package
     *  name.
     * @param section The section to visit the entries of.
     */
    public void visit(Section section){
      for(Entry entry : section.entries){
        if(entry instanceof ToolEntry){
          ToolEntry toolentry = (ToolEntry) entry;
         
          visit(toolentry, section.id);
        }
      }
    }
    /***
     * Visit all the sections in a toolbox object.
     * @param toolbox Toolbox to visit.
     */
    public void visit(Toolbox toolbox){
    for(Section section : toolbox.sections){
      visit(section);
    }
  }
  }
  /**
   * Setup the tool index parser to parse the tool index file correctly
   *  and load the tool database.
   */
  public GalaxyToolDatabase(){
    //Path, package, tool
    toolDB = new HashMap<String, Triple<String,String, Tool>>();
    toolIndexParser = new XStreamWrapper<Toolbox>();
   
    toolIndexParser.bindElementToClass(Toolbox.class, "toolbox");
    toolIndexParser.bindGroupToList(Toolbox.class, "sections", Section.class);
   
    toolIndexParser.bindElementToClass(Section.class, "section");
    toolIndexParser.bindAttributeToClassField(Section.class, "name", "name");
    toolIndexParser.bindAttributeToClassField(Section.class, "id", "id");
    toolIndexParser.bindGroupToList(Section.class, "entries", Entry.class);
   
    toolIndexParser.bindElementToClass(ToolEntry.class, "tool");
    toolIndexParser.bindAttributeToClassField(ToolEntry.class, "path", "file");
   
    toolIndexParser.bindElementToClass(LabelEntry.class,  "label");
    toolIndexParser.bindAttributeToClassField(LabelEntry.class, "label", "text");
    toolIndexParser.bindAttributeToClassField(LabelEntry.class, "label", "text");
   
   
    loadDatabase();
  }
  /***
   * Clear the database and the tool index object.
   */
  public void clear(){
    toolDB.clear();
    toolIndex = null;
  }
  /**
   * Load the database from the Galaxy input directory.
   */
  private void loadDatabase(){
    try {
      ToolIndexVisitor indexVisitor = new ToolIndexVisitor();
      toolIndex = toolIndexParser.parse(new File(ConverterConfig.GALAXY_INPUT_DIR + INDEX_NAME));
      indexVisitor.visit(toolIndex);
   
    } catch (FileNotFoundException e) {
      // TODO Auto-generated catch block
      Printer.log("Error Parsing "+ConverterConfig.GALAXY_INPUT_DIR + INDEX_NAME);
     
      Printer.log("Galaxy Directory not found: Cannot load tools");
     
    }
  }
  /**
   * Dump the tool database to the Galaxy output directory. Dumps the updated index file
   * and all the tools in their appropriate directories. Tools that cannot be dumped are skipped.
   */
  public void dumpDatabase(){
    String idxPath = ConverterConfig.GALAXY_OUTPUT_DIR + INDEX_NAME;
    try {
      (new File(idxPath)).createNewFile();
    } catch (IOException e1) {
      System.err.println("Index file  creation failed.");
    }
    if(toolIndex != null){
      try {
        toolIndexParser.generate(toolIndex, idxPath);
      }
      catch (IOException e) {
        // TODO Auto-generated catch block
        System.err.println(e.getMessage());
        e.printStackTrace();
      }
    }
    for(String id : toolDB.keySet()){
      Triple<String, String, Tool> currentTool = toolDB.get(id);
      String relativePath = currentTool.getElem1();
      Tool toolToDump = currentTool.getElem3();
      if(toolToDump != null&& relativePath != null ){
        File dir = new File(relativePathToOutputToolPath(getDirectory(id)));
        File absfile = new File(relativePathToOutputToolPath(relativePath));
        dir.mkdirs();
        try {
          absfile.createNewFile();
        } catch (IOException e1) {
          System.err.println("File  creation failed.");
         
        }
        try {
          GalaxySpecification.getXMLGenerator().generate(toolToDump, absfile.getAbsolutePath());
        } catch (IOException e) {
          // TODO Auto-generated catch block
          System.err.println(e.getLocalizedMessage());
          System.err.println(e.getMessage());
          e.printStackTrace();
        }
      }
       
    }
  }
  /**
   * Get a section of the tool index file by the id of the section.
   * return null if the section doesn't exist.
   * @param sectionName name of section to get.
   * @return section with specified name.
   */
  private Section getSection(String sectionName){
    if(sectionName == null)
      return null;
    if(toolIndex == null || toolIndex.sections == null)
      return null;
    for(Section section : toolIndex.sections){
      if(section.id.equals(sectionName))
        return section;
    }
    return null;
  }
  /***
   * Add a new section with the given section id.  If the section already
   * exists, return the existing section. If it doesn't, create a new section,
   * add it to the tool index object and return the new section. The created section
   * will have an id and name that corresponds to the specified section name.
   * @param sectionName The name the created/retrieved section should have as an id.
   * @return The found/created section.
   */
  private Section addSection(String sectionName){
    if(toolIndex == null)
      toolIndex = new Toolbox();
    if(toolIndex.sections == null)
      toolIndex.sections = new LinkedList<Section>();
    for(Section section : toolIndex.sections){
      if(section.id.equals(sectionName))
        return section;
    }
    Section newSect = new Section();
    newSect.name = sectionName;
    newSect.id = sectionName;
    newSect.entries = new LinkedList<Entry>();
    toolIndex.sections.add(newSect);
    return newSect;
  }
 
  /**
   * Get the enclosing package name given the id of a tool.
   * @param id the id of the tool to get the package of.
   * @return the name of the package.
   */
  public String getPackage(String id){
    if(toolDB.containsKey(id))
      return toolDB.get(id).getElem2();
   
    return "";
  }
  /**
   * Get the directory of the tool with the specified id. For example if
   * the tool's path is foo/a/test.xml, the returned directory will be
   * foo/a/
   * @param id The id of the tool to get the directory of.
   * @return The directory path.
   */
  public String getDirectory(String id){
    String tooldir = "";
    if(toolDB.containsKey(id)){
      String path =toolDB.get(id).getElem1();
      String[] args = path.split("/");
      for(int i=0; i<args.length-1; i++){
        tooldir += args[i] + "/";
      }
    }
    return tooldir;
  }
  /**
   * Get the path of a tool from the id. For example if the path of
   * some tool is foo/A/test.xml, then, foo/A/test.xml is returned.
   * If the tool doesn't exist return an empty string.
   * @param id id of the tool to get the path of.
   * @return
   */
  public String getPath(String id){
    ;
    if(toolDB.containsKey(id))
      return toolDB.get(id).getElem1();
   
    return "";
  }
  /***
   * Given the desired id, return a modified version of the desired id
   * that does not conflict with any of the existing tools in the database.
   * @param baseid The desired id for the tool.
   * @return An id based on the desired id that does not conflict with the ids of
   * any existing tools.
   */
  public String getUniqueToolID(String  baseid){
    String id = baseid;
    int count = 0;
    while(toolDB.containsKey(id)){
      id = baseid + count;
      count++;
    }
    return id;
  }
  /***
   * Add a tool to the database given the package the tool is a part of and a
   * Tool object. Creates a new tool_entry in the tool index file, and
   * as adds a the tool to the tool database. the tool's filename is generated
   * from the tool id.
   * @param packageName The package name of the tool to add.
   * @param tool The tool to add.
   */
  public void addTool(String packageName,Tool tool){
    String id = tool.getID();
    String package_ = packageName;
    String mypath =  ToolPairToRelativePath(id,packageName);
   
    toolDB.put(id, new Triple(mypath, package_, tool));
    /*
     * Add to index tree.
     */
    ToolEntry toolEntry = new ToolEntry();
    toolEntry.path = mypath;
    Section idxSection = getSection(packageName);
    if(idxSection == null){
      idxSection = addSection(packageName);
    }
    idxSection.entries.add(toolEntry);
   
   
  }
  /**
   * Retrieves a tool object from the database using the provided tool id. If
   * the tool object is not loaded into the database, its .xml specification file is
   * parsed and the tool is loaded. If the key is not found, then null is returned.
   * @param toolId the id name of the tool to retrieve.
   * @return the tool object in the database.
   */
  public Tool getTool(String toolId){
   
      if(toolDB.containsKey(toolId)){
        Tool tool;
        Triple<String, String, Tool> databaseTool= toolDB.get(toolId);
        /*
        If the tool has never been parsed. Parse it and store it.
        */
        if(databaseTool.getElem3() == null){
          try {
           
            tool = GalaxySpecification.getXMLParser().parse(
                new File(relativePathToInputToolPath(databaseTool.getElem1())
                ));
            if(tool == null)
              throw new RuntimeException("Tool did not parse correctly");
            databaseTool.setElem3(tool);
          } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            System.err.print("FILE: "+databaseTool.getElem1());
            System.err.print(toolId);
            System.err.print(e.getMessage());
            e.printStackTrace();
          }
         
        }
        return databaseTool.getElem3();
      }
    return null;
  }
 
}
TOP

Related Classes of Galaxy.Toolbox.GalaxyToolDatabase$Entry

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.