예제 #1
0
/** NominalValue Adapter */
@Deprecated
public class DeprecatedNominalValue extends DeprecatedValue implements NominalValue {

  private static final Logger LOGGER = UserMetrix.getLogger(DeprecatedNominalValue.class);

  public DeprecatedNominalValue(final Database db, final long cellID) {
    super(db, cellID);
  }

  @Override
  public boolean isValid(final String value) {
    return true;
  }

  @Override
  public void set(final String value) {
    try {
      DataCell dc = (DataCell) legacyDB.getCell(legacyCellID);
      Matrix m = dc.getVal();
      NominalDataValue dv = (NominalDataValue) m.getArgCopy(0);
      dv.setItsValue(value);
      m.replaceArg(0, dv);
      dc.setVal(m);
      legacyDB.replaceCell(dc);
    } catch (SystemErrorException se) {
      LOGGER.error("unable to set text data value", se);
    }
  }

  @Override
  public String toString() {
    try {
      DataCell dc = (DataCell) legacyDB.getCell(legacyCellID);

      if (isEmpty()) {
        DataColumn col = legacyDB.getDataColumn(dc.getItsColID());
        return "<" + col.getName() + ">";
      } else {
        Matrix m = dc.getVal();
        NominalDataValue dv = (NominalDataValue) m.getArgCopy(0);
        return dv.getItsValue();
      }

    } catch (SystemErrorException se) {
      LOGGER.error("unable to toString data value", se);
    }

    return "<ERROR - RESTART OPENSHAPA>";
  }
}
예제 #2
0
public abstract class VocabEditorEdit extends SpreadsheetEdit {
  /** The logger for this class. */
  private static final Logger LOGGER = UserMetrix.getLogger(VocabEditorEdit.class);

  public VocabEditorEdit() {
    super();
  }

  @Override
  public String getPresentationName() {
    return "";
  }

  @Override
  public void undo() throws CannotRedoException {
    super.undo();
  }

  @Override
  public void redo() throws CannotUndoException {
    super.redo();
  }
}
예제 #3
0
/** Controller for opening a database from disk. */
public final class OpenDatabaseFileC {

  /** The index of the ONSET timestamp in the CSV line. */
  private static final int DATA_ONSET = 0;

  /** The index of the OFFSET timestamp in the CSV line. */
  private static final int DATA_OFFSET = 1;

  /** The start of the data arguments. */
  private static final int DATA_INDEX = 2;

  /** The logger for this class. */
  private static Logger LOGGER = UserMetrix.getLogger(OpenDatabaseFileC.class);

  /**
   * Opens a database.
   *
   * @param sourceFile The source file to open.
   * @return populated MacshapaDatabase on success, null otherwise.
   */
  public Datastore open(final File sourceFile) {
    Datastore db;
    String inputFile = sourceFile.toString().toLowerCase();

    // If the file ends with CSV - treat it as a comma seperated file.
    if (inputFile.endsWith(".csv")) {
      db = openAsCSV(sourceFile);

      // Otherwise treat it as a macshapa database file.
    } else {
      db = openAsMacSHAPADB(sourceFile);
    }

    return db;
  }

  /**
   * This method treats a file as a MacSHAPA database file and attempts to populate the database
   * with data.
   *
   * @param sFile The source file to use when populating the database.
   * @return populated database on success, null otherwise.
   */
  public Datastore openAsMacSHAPADB(final File sFile) {

    // Currently no implementation of opening older MacSHAPA database.
    // ... One day.

    // Error occured - return null.
    return null;
  }

  /**
   * This method parses a CSV file and populates the database (and spreadsheet) with data.
   *
   * @param sFile The source file to use when populating the database.
   * @return populated database on success, null otherwise.
   */
  public Datastore openAsCSV(final File sFile) {

    try {
      LOGGER.event("open csv database from file");

      FileInputStream fis = new FileInputStream(sFile);
      Datastore result = openAsCSV(fis);
      fis.close();

      return result;
    } catch (Exception fe) {
      LOGGER.error("Unable to open as CSV", fe);
    }

    // Error encountered - return null.
    return null;
  }

  /**
   * This method parses a CSV input stream and populates the database (and spreadsheet) with data.
   * The caller is responsible for managing the stream.
   *
   * @param inStream The stream to deserialized when populating the database.
   * @return populated database on sucess, null otherwise.
   */
  public Datastore openAsCSV(final InputStream inStream) {
    try {
      LOGGER.event("open csv database from stream");

      Datastore db = DatastoreFactory.newDatastore();
      db.setTitleNotifier(OpenSHAPA.getApplication());
      InputStreamReader isr = new InputStreamReader(inStream);
      BufferedReader csvFile = new BufferedReader(isr);

      // Read each line of the CSV file.
      String line = csvFile.readLine();

      // If we have a version identifier parse the file using the schema
      // that matches that identifier.
      if ("#4".equalsIgnoreCase(line)) {

        // Version 4 includes a comment for columns.
        line = parseDefinitions(csvFile, db);

        while (line != null) {
          line = parseVariable(csvFile, line, db, "#4");
        }
      } else if ("#3".equalsIgnoreCase(line)) {

        // Version 3 includes column visible status after the column type
        // Parse predicate definitions first.
        line = parseDefinitions(csvFile, db);

        while (line != null) {
          line = parseVariable(csvFile, line, db, "#3");
        }
      } else if ("#2".equalsIgnoreCase(line)) {

        // Parse predicate definitions first.
        line = parseDefinitions(csvFile, db);

        while (line != null) {
          line = parseVariable(csvFile, line, db);
        }

      } else {

        // Use the original schema to load the file - just variables,
        // and no escape characters.
        while (line != null) {
          line = parseVariable(csvFile, line, db);
        }
      }

      csvFile.close();
      isr.close();

      return db;
    } catch (IOException e) {
      LOGGER.error("Unable to read line from CSV file", e);
    } catch (UserWarningException e) {
      LOGGER.error("Unable to create new variable.", e);
    }

    // Error encountered - return null.
    return null;
  }

  /**
   * Strips escape characters from a line of text.
   *
   * @param line The line of text to strip escape characters from.
   * @return The line free of escape characters, i.e. '\'.
   */
  private String stripEscChars(final String line) {
    String result = null;

    if (line != null) {
      result = "";

      for (int i = 0; i < line.length(); i++) {

        if (i < (line.length() - 1)) {

          if ((line.charAt(i) == '\\') && (line.charAt(i + 1) == '\\')) {
            char[] buff = {'\\'};
            result = result.concat(new String(buff));

            // Move over the escape character.
            i++;
          } else if ((line.charAt(i) == '\\') && (line.charAt(i + 1) == ',')) {
            char[] buff = {','};
            result = result.concat(new String(buff));

            // Move over the escape character.
            i++;
          } else if ((line.charAt(i) == '\\') && (line.charAt(i + 1) == '-')) {
            char[] buff = {'-'};
            result = result.concat(new String(buff));

            // Move over the escape character.
            i++;
          } else {
            result += line.charAt(i);
          }
        } else {
          result += line.charAt(i);
        }
      }
    }

    return result;
  }

  /**
   * Method to invoke when we encounter a block of text in the CSV file that is the contents of a
   * predicate variable.
   *
   * @param csvFile The csvFile we are currently parsing.
   * @param dc The variable that we will be adding cells too.
   * @return The next line in the file that is not part of the block of text in the CSV file.
   * @throws IOException If unable to read the file correctly.
   */
  /* TODO: PREDICATE VARIABLES CURRENTLY UNSUPPORTED
  private String parsePredicateVariable(final BufferedReader csvFile,
                                        final DataColumn dc)
  throws IOException, SystemErrorException {

      // Keep parsing lines and putting them in the newly formed nominal
      // variable until we get to a line indicating the end of file or a new
      // variable section.
      String line = csvFile.readLine();

      while ((line != null) && Character.isDigit(line.charAt(0))) {

          // Split the line into tokens using '\,' '(' & ')' as delimiters.
          String[] tokens = line.split("[,\\()]");

          // Create the data cell from line in the CSV file.
          DataCell cell = new DataCell(dc.getDB(), dc.getID(),
                  dc.getItsMveID());

          // Set the onset and offset from tokens in the line.
          cell.setOnset(new TimeStamp(tokens[DATA_ONSET]));
          cell.setOffset(new TimeStamp(tokens[DATA_OFFSET]));

          // Empty predicate - just add the empty data cell.
          if (tokens.length == DATA_INDEX) {

              // Add the populated cell to the database.
              dc.getDB().appendCell(cell);

          } else {

              // Non empty predicate - need to check if we need to add an
              // entry to the vocab, and create it if it doesn't exist.
              // Otherwise we just plow ahead and add the predicate to the
              // database.
              PredicateVocabElement pve = dc.getDB().getPredVE(
                      tokens[DATA_INDEX]);

              Predicate p = new Predicate(dc.getDB(), pve.getID(),
                      parseFormalArgs(tokens, DATA_INDEX + 1, dc, pve));
              PredDataValue pdv = new PredDataValue(dc.getDB());
              pdv.setItsValue(p);

              // Insert the datavalue in the cell.
              long mveId = dc.getDB().getMatrixVE(dc.getItsMveID()).getID();
              Matrix m = Matrix.Construct(dc.getDB(), mveId, pdv);
              cell.setVal(m);

              // Add the populated cell to the database.
              dc.getDB().appendCell(cell);
          }

          // Get the next line in the file for reading.
          line = csvFile.readLine();
      }

      return line;
  }
  */

  /**
   * Method to create data values for the formal arguments of a vocab element.
   *
   * @param tokens The array of string tokens.
   * @param startI The starting index to
   * @param destValue The destination value that we are populating.
   */
  private void parseFormalArgs(
      final String[] tokens,
      final int startI,
      final Argument destPattern,
      final MatrixValue destValue) {

    for (int i = 0; i < destValue.getArguments().size(); i++) {
      Argument fa = destPattern.childArguments.get(i);
      boolean emptyArg = false;

      // If the field doesn't contain anything or matches the FargName
      // we consider the argument to be 'empty'.
      if ((tokens[startI + i].length() == 0) || tokens[startI + i].equals(fa.name)) {
        emptyArg = true;
      }

      tokens[startI + i] = tokens[startI + i].trim();
      destValue.getArguments().get(i).set(tokens[startI + i]);
    }
  }

  /**
   * Method to invoke when we encounter a block of text in the CSV file that is the contents of a
   * predicate variable.
   *
   * @param csvFile The csvFile we are currently parsing.
   * @param var The variable that we will be adding cells too.
   * @param arg The matrix template we are using when parsing individual matrix elements to put in
   *     the spreadsheet.
   * @return The next line in the file that is not part of the block of text in the CSV file.
   * @throws IOException If unable to read the file correctly.
   */
  private String parseMatrixVariable(
      final BufferedReader csvFile, final Variable var, final Argument arg) throws IOException {
    String line = csvFile.readLine();

    while ((line != null) && Character.isDigit(line.charAt(0))) {

      // Split the line into tokens using a comma delimiter.
      String[] tokens = line.split(",");

      Cell newCell = var.createCell();
      // Set the onset and offset from tokens in the line.
      newCell.setOnset(tokens[DATA_ONSET]);
      newCell.setOffset(tokens[DATA_OFFSET]);

      // Strip the brackets from the first and last argument.
      tokens[DATA_INDEX] = tokens[DATA_INDEX].substring(1, tokens[DATA_INDEX].length());

      int end = tokens.length - 1;
      tokens[end] = tokens[end].substring(0, tokens[end].length() - 1);
      parseFormalArgs(tokens, DATA_INDEX, var.getVariableType(), (MatrixValue) newCell.getValue());

      // Get the next line in the file for reading.
      line = csvFile.readLine();
    }

    return line;
  }

  /**
   * Method to invoke when we encounter a block of text in the CSV file that is the contents of a
   * variable.
   *
   * @param csvFile The csvFile we are currently parsing.
   * @param var The variable that we will be adding cells too.
   * @param The populator to use when converting the contents of the cell into a datavalue that can
   *     be inserted into the spreadsheet.
   * @return The next line in the file that is not part of the block of text in the CSV file.
   * @throws IOException If unable to read the file correctly.
   */
  private String parseEntries(
      final BufferedReader csvFile, final Variable var, final EntryPopulator populator)
      throws IOException {

    // Keep parsing lines and putting them in the newly formed nominal
    // variable until we get to a line indicating the end of file or a new
    // variable section.
    String line = csvFile.readLine();

    while ((line != null) && Character.isDigit(line.charAt(0))) {

      // Split the line into tokens using a comma delimiter.
      String[] tokens = line.split(",");

      // BugzID: 1075 - If the line ends with an escaped new line - add
      // the next line to the current text field.
      while ((line != null) && line.endsWith("\\") && !line.endsWith("\\\\")) {
        line = csvFile.readLine();

        String content = tokens[tokens.length - 1];
        content = content.substring(0, content.length() - 1);
        tokens[tokens.length - 1] = content + '\n' + line;
      }

      Cell newCell = var.createCell();

      // Set the onset and offset from tokens in the line.
      newCell.setOnset(tokens[DATA_ONSET]);
      newCell.setOffset(tokens[DATA_OFFSET]);
      populator.populate(tokens, newCell.getValue());

      // Get the next line in the file for reading.
      line = csvFile.readLine();
    }

    return line;
  }

  /**
   * Parses the predicate definitions from the CSV file.
   *
   * @param csvFile The buffered reader containing the contents of the CSV file we are trying parse.
   * @param ds The destination datastore for the csv file.
   * @return The next line to be parsed from the file.
   * @throws IOException If unable to read from the csvFile.
   */
  private String parseDefinitions(final BufferedReader csvFile, final Datastore db)
      throws IOException {

    // Keep parsing lines and putting them in the newly formed nominal
    // variable until we get to a line indicating the end of file or a new
    // variable section.
    String line = csvFile.readLine();

    while ((line != null) && Character.isDigit(line.charAt(0))) {

      /*
       * TODO Parsing predicates.
       *
      // Parse arguments - for predicate vocab element.
      String[] token = line.split(":|(?<!\\\\)-");
      PredicateVocabElement pve = new PredicateVocabElement(db,
              this.stripEscChars(token[1]));

      for (String arg : token[2].split(",")) {
          pve.appendFormalArg(parseFormalArgument(arg, db));
      }

      db.addPredVE(pve);
      */

      // Get the next line in the file for reading.
      line = csvFile.readLine();
    }

    return line;
  }

  /**
   * Method to build a formal argument.
   *
   * @param content The string holding the formal argument content to be parsed.
   * @param db The parent database for the formal argument.
   * @return The formal argument.
   */
  private Argument parseFormalArgument(final String content) {
    Argument fa;
    String[] formalArgument = content.split("\\|");
    formalArgument[0] = this.stripEscChars(formalArgument[0]);

    // Add text formal argument.
    if (formalArgument[1].equalsIgnoreCase("quote_string")) {
      fa = null;

    } else if (formalArgument[1].equalsIgnoreCase("integer")) {
      // Add integer formal argument.
      fa = null;

    } else if (formalArgument[1].equalsIgnoreCase("float")) {
      // Add float formal argument.
      fa = null;

    } else {
      // Add nominal formal argument.
      fa = new Argument(formalArgument[0], Argument.Type.NOMINAL);
    }

    return fa;
  }

  /**
   * Method to invoke when we encounter a block of text that is a variable.
   *
   * @param csvFile The CSV file we are currently reading.
   * @param line The line of the CSV file we are currently reading.
   * @param db The data store we are populating with data from the CSV file.
   * @return The next String that is not part of the currently variable that we are parsing.
   * @throws IOException When we are unable to read from the csvFile.
   * @throws UserWarningException When we are unable to create a new variable.
   */
  private String parseVariable(final BufferedReader csvFile, final String line, final Datastore db)
      throws IOException, UserWarningException {
    return parseVariable(csvFile, line, db, "#2");
  }

  /**
   * Method to invoke when we encounter a block of text that is a variable.
   *
   * @param csvFile The CSV file we are currently reading.
   * @param line The line of the CSV file we are currently reading.
   * @param db The data store we are populating with data from the CSV file.
   * @return The next String that is not part of the currently variable that we are parsing.
   * @throws IOException When we are unable to read from the csvFile.
   * @throws UserWarningException When we are unable to create variables.
   */
  private String parseVariable(
      final BufferedReader csvFile, final String line, final Datastore ds, final String version)
      throws IOException, UserWarningException {
    // Determine the variable name and type.
    String[] tokens = line.split("\\(");
    String varName = this.stripEscChars(tokens[0].trim());
    String varType = null;
    String varComment = "";
    boolean varVisible = true;

    if (version.equals("#4")) {
      String[] varArgs = tokens[1].split(",");
      varType = varArgs[0];
      varVisible = Boolean.parseBoolean(varArgs[1]);
      varComment = varArgs[2].substring(0, varArgs[2].indexOf(")"));
    } else if (version.equals("#3")) {
      varType = tokens[1].substring(0, tokens[1].indexOf(","));
      varVisible =
          Boolean.parseBoolean(
              tokens[1].substring(tokens[1].indexOf(",") + 1, tokens[1].indexOf(")")));
    } else {
      varType = tokens[1].substring(0, tokens[1].indexOf(")"));
    }

    // BugzID:1703 - Ignore old macshapa query variables, we don't have a
    // reliable mechanisim for loading their predicates. Given problems
    // between the untyped nature of macshapa and the typed nature of
    // OpenSHAPA.
    if (varName.equals("###QueryVar###")) {
      String lineEater = csvFile.readLine();

      while ((lineEater != null) && Character.isDigit(lineEater.charAt(0))) {
        lineEater = csvFile.readLine();
      }

      return lineEater;
    }

    // Create variable to put cells within.
    Argument.Type variableType = getVarType(varType);
    Variable newVar = ds.createVariable(varName, variableType);
    newVar.setHidden(!varVisible);

    // Read text variable.
    if (variableType == Argument.Type.TEXT) {
      return parseEntries(csvFile, newVar, new PopulateText());

    } else if (variableType == Argument.Type.NOMINAL) {
      // Read nominal variable.
      return parseEntries(csvFile, newVar, new PopulateNominal());

    } /* else if (getVarType(varType)
              == MatrixVocabElement.MatrixType.INTEGER) {
          // Read integer variable.
          return parseEntries(csvFile,
                              newVar.getLegacyVariable(),
                              new PopulateInteger(legacyDb));

      } else if (getVarType(varType) == MatrixVocabElement.MatrixType.FLOAT) {
          return parseEntries(csvFile,
                              newVar.getLegacyVariable(),
                              new PopulateFloat(legacyDb));

      }*/ else if (variableType == Argument.Type.MATRIX) {

      // Read matrix variable - Build vocab for matrix.
      String[] vocabString = tokens[1].split("(?<!\\\\)-");

      // Get the vocab element for the matrix and clean it up to be
      // populated with arguments from the CSV file.
      Argument newArg = newVar.getVariableType();
      // MatrixVocabElement mve = legacyDb.getMatrixVE(varName);
      // mve.deleteFormalArg(0);

      // For each of the formal arguments in the file - parse it and
      // create a formal argument in the matrix vocab element.
      for (String arg : vocabString[1].split(",")) {
        newArg.childArguments.add(parseFormalArgument(arg));
      }
      newVar.setVariableType(newArg);

      return parseMatrixVariable(csvFile, newVar, newArg);

      // Read predicate variable.
    } /*else if (getVarType(varType)
              == MatrixVocabElement.MatrixType.PREDICATE) {
          return parsePredicateVariable(csvFile, newVar.getLegacyVariable());
      }*/

    throw new IllegalStateException("Unknown variable type.");
  }

  /**
   * @param type The string containing the variable type.
   * @return The type of the variable.
   */
  private Argument.Type getVarType(final String type) {

    if (type.equalsIgnoreCase("text")) {
      return Argument.Type.TEXT;

    } else if (type.equalsIgnoreCase("nominal")) {
      return Argument.Type.NOMINAL;

    } else if (type.equalsIgnoreCase("predicate")) {
      // TODO - support predicate types.
      return null;

    } else if (type.equalsIgnoreCase("matrix")) {
      return Argument.Type.MATRIX;

    } else if (type.equalsIgnoreCase("integer")) {
      // TODO - support integer types.
      return null;

    } else if (type.equalsIgnoreCase("float")) {
      // TODO - support float types.
      return null;
    }

    // Error - Unknown type.
    return null;
  }

  /**
   * A populator for creating data values that can be used to populate database spreadsheet cells.
   */
  private abstract class EntryPopulator {

    /**
     * Populates a DataValue from the supplied array of tokens.
     *
     * @param tokens The tokens to use when building a DataValue.
     * @param destValue That this populator is filling with content.
     */
    abstract void populate(final String[] tokens, final Value destValue);
  }

  /** EntryPopulator for creating integer values. */
  private class PopulateInteger extends EntryPopulator {

    /**
     * Populates a DataValue from the supplied array of tokens.
     *
     * @param tokens The tokens to use when building a DataValue.
     * @param destValue That this populator is filling with content.
     */
    @Override
    void populate(final String[] tokens, final Value destValue) {
      /*
      IntDataValue idv = new IntDataValue(getDatabase());

      // BugzID:722 - Only populate the value if we have one from the file
      if (tokens.length > DATA_INDEX) {
          idv.setItsValue(tokens[DATA_INDEX]);
      }

      return idv;
      */

      // TODO: Support integer values.
    }
  }

  /** EntryPopulator for creating float values. */
  private class PopulateFloat extends EntryPopulator {

    /**
     * Populates a DataValue from the supplied array of tokens.
     *
     * @param tokens The tokens to use when building a DataValue.
     * @param destValue That this populator is filling with content.
     */
    @Override
    void populate(final String[] tokens, final Value destValue) {
      /*
      FloatDataValue fdv = new FloatDataValue(getDatabase());

      // BugzID:722 - Only populate the value if we have one from the file
      if (tokens.length > DATA_INDEX) {
          fdv.setItsValue(tokens[DATA_INDEX]);
      }

      return fdv;
      */

      // TODO - Implement.
    }
  }

  /** EntryPopulator for creating nominal data values. */
  private class PopulateNominal extends EntryPopulator {

    /**
     * Populates a DataValue from the supplied array of tokens.
     *
     * @param tokens The tokens to use when building a DataValue.
     * @param destValue That this populator is filling with content.
     */
    @Override
    void populate(final String[] tokens, final Value destValue) {
      // BugzID:722 - Only populate the value if we have one from the file
      if (tokens.length > DATA_INDEX) {
        destValue.set(stripEscChars(tokens[DATA_INDEX]));
      }
    }
  }

  /** EntryPopulator for creating text data values. */
  private class PopulateText extends EntryPopulator {

    /**
     * Populates a DataValue from the supplied array of tokens.
     *
     * @param tokens The tokens to use when building a DataValue.
     * @param destValue That this populator is filling with content.
     */
    @Override
    void populate(final String[] tokens, final Value destValue) {
      // BugzID:722 - Only populate the value if we have one from the file
      if (tokens.length > DATA_INDEX) {
        String text = "";

        for (int i = DATA_INDEX; i < tokens.length; i++) {
          text = text.concat(tokens[i]);

          if (i < (tokens.length - 1)) {
            text = text.concat(",");
          }
        }

        destValue.set(stripEscChars(text));
      }
    }
  }
}