Example #1
0
 private void updateProjectCache() {
   // Ensure we have a cache at all:
   initProjectCache();
   // Loop through project path preference keys:
   for (Map.Entry<String, ?> entry : preferences.getAll().entrySet())
     if (entry.getKey().startsWith(PREF_PROJECT_PATH_PREFIX)
         && entry.getKey().endsWith(PREF_PROJECT_PATH_POSTFIX)) {
       int projectID = getProjectID(entry.getKey());
       int projectFingerPrint = getProjectFingerPrint(entry.getKey());
       if (getCachedProject(projectID, projectFingerPrint)
           == null) { // Parse the project if it is not already in the cache:
         Project p = ProjectLoader.ParseProject(entry.getValue().toString());
         if (p != null) {
           if (p.getFingerPrint() != projectFingerPrint) {
             Log.w(
                 TAG,
                 "XML finger print of project "
                     + p.toString()
                     + " has changed, possibly the "
                     + ProjectLoader.PROJECT_FILE
                     + " file (located in "
                     + entry.getValue().toString()
                     + ") was manually edited!");
             // Remove old pref key:
             removeProjectPathPrefKey(projectID, projectFingerPrint);
             // Add new pref key:
             storeProjectPathPrefKey(p);
           }
           // Cache the project object:
           cacheProject(p);
         }
       }
     }
 }
Example #2
0
 /**
  * Gets project from cache if it is there, returns null otherwise
  *
  * @param projectID
  * @param projectFingerPrint
  * @return
  */
 private Project getCachedProject(int projectID, int projectFingerPrint) {
   if (projectCache != null)
     for (Project cachedProj : projectCache)
       if (cachedProj.getID() == projectID && cachedProj.getFingerPrint() == projectFingerPrint)
         return cachedProj;
   return null;
 }
  /* (non-Javadoc)
   * @see uk.ac.ucl.excites.sapelli.collector.db.ProjectStore#serialise(uk.ac.ucl.excites.sapelli.collector.model.Project, java.io.OutputStream)
   */
  @Override
  public void serialise(Project project, OutputStream out) throws IOException {
    // Project XML bytes:
    InputStream projectXMLFileIn =
        new FileInputStream(ProjectLoader.GetProjectXMLFile(getProjectFolder(project)));
    ByteArrayOutputStream projectXMLBytesOut = new ByteArrayOutputStream();
    IOUtils.copy(projectXMLFileIn, projectXMLBytesOut);
    projectXMLFileIn.close();
    projectXMLBytesOut.close();

    // FSI record bytes for each Form:
    List<byte[]> fsiRecordBytesList = new ArrayList<>(project.getNumberOfForms());
    for (Form form : project.getForms()) {
      Record fsiRecord = retrieveFSIRecord(form); // we query the projectStore to save time...
      if (fsiRecord == null) // ... but we don't rely on it:
      fsiRecord = getFSIRecord(form); // may trigger optionality analysis
      fsiRecordBytesList.add(fsiRecord.toBytes(true));
    }

    // Create serialisedProject valueSet:
    ValueSet<ColumnSet> serialisedProjectVS =
        new ValueSet<ColumnSet>(
            PROJECT_SERIALISIATION_CS, projectXMLBytesOut.toByteArray(), fsiRecordBytesList);

    // Return as byte array:
    BitOutputStream bitsOut = new BitWrapOutputStream(out);
    serialisedProjectVS.writeToBitStream(bitsOut, true);
    bitsOut.flush();
  }
Example #4
0
 @Override
 public List<Project> retrieveProjectVersions(int projectID) {
   updateProjectCache(); // will also call initProjectCache()
   List<Project> projectVersions = new ArrayList<Project>();
   for (Project project : projectCache)
     if (project.getID() == projectID) projectVersions.add(project);
   return projectVersions;
 }
Example #5
0
 /* (non-Javadoc)
  * @see uk.ac.ucl.excites.sapelli.collector.database.IDataAccess#retrieveV1Project(int, int)
  */
 @Override
 public Project retrieveV1Project(final int schemaID, final int schemaVersion) {
   updateProjectCache(); // will also call initProjectCache()
   for (Project project : projectCache)
     if (project.isV1xProject()
         && project.getID() == schemaID
         && project.getV1XSchemaVersion() == schemaVersion) return project;
   return null;
 }
Example #6
0
 /**
  * Retrieves specific Project
  *
  * @return the project object or null if project was not found
  */
 @Override
 public Project retrieveProject(final String name, final String variant, final String version) {
   updateProjectCache(); // will also call initProjectCache()
   for (Project project : projectCache) {
     if (project.getName().equalsIgnoreCase(name)
         && (variant != null ? variant.equals(project.getVariant()) : true)
         && project.getVersion().equalsIgnoreCase(version)) return project;
   }
   return null;
 }
 @Override
 public void deleteSendSchedulesForProject(Project project) {
   try {
     if (project != null)
       rsWrapper.recordStore.delete(
           new RecordsQuery(
               SEND_SCHEDULE_SCHEMA,
               new EqualityConstraint(
                   SEND_SCHEDULE_COLUMN_PROJECT, getProjectRecordReference(project))));
   } catch (DBException e) {
     rsWrapper.client.logError(
         "Error upon deleting SendSchedules for Project \"" + project.toString(false) + "\".", e);
   }
 }
 private Record getProjectRecord(Project project) {
   Record projRec = PROJECT_SCHEMA.createRecord();
   PROJECT_ID_COLUMN.storeValue(projRec, project.getID());
   PROJECT_FINGERPRINT_COLUMN.storeValue(projRec, project.getFingerPrint());
   PROJECT_NAME_COLUMN.storeValue(projRec, project.getName());
   String projVariant = project.getVariant();
   PROJECT_VARIANT_COLUMN.storeValue(
       projRec, projVariant != null ? projVariant : ""); // replace null by empty string!
   PROJECT_VERSION_COLUMN.storeValue(projRec, project.getVersion());
   PROJECT_V1X_SCHEMA_VERSION_COLUMN.storeValue(projRec, project.getV1XSchemaVersion());
   return projRec;
 }
 /* (non-Javadoc)
  * @see uk.ac.ucl.excites.sapelli.collector.db.ProjectStore#doAdd(uk.ac.ucl.excites.sapelli.collector.model.Project)
  */
 @Override
 protected void doAdd(Project project)
     throws ProjectIdentificationClashException, ProjectSignatureClashException,
         IllegalStateException {
   try { // Note: we use insert() instead of store() to not allow updates
     // Store project record:
     rsWrapper.recordStore.insert(getProjectRecord(project));
     // Store an FSI record for each record-producing form:
     for (Form form : project.getForms())
       if (form.isProducesRecords()) rsWrapper.recordStore.insert(getFSIRecord(form));
     // Cache the project:
     cacheProject(project);
   } catch (DBPrimaryKeyException dbPKE) {
     throw new ProjectIdentificationClashException(project, false);
   } catch (DBConstraintException dbCE) {
     throw new ProjectSignatureClashException(project);
   } catch (DBException e) {
     e.printStackTrace(System.err);
     throw new IllegalStateException(e);
   }
 }
Example #10
0
 private String getProjectPathPrefKey(Project project) {
   return getProjectPathPrefKey(project.getID(), project.getFingerPrint());
 }
Example #11
0
  @Override
  protected void parseEndElement(String uri, String localName, String qName) throws Exception {
    // </Sapelli-Collector-Project>, or </ExCiteS-Collector-Project> (for backwards compatibility)
    if (qName.equals(TAG_PROJECT) || qName.equals(TAG_PROJECT_V1X)) {
      clearSubtreeParsers();

      if (project.getForms().size() == 0)
        throw new SAXException("A project such have at least 1 form!");
      else {
        // Resolve startForm
        Form startForm =
            project.getForm(
                startFormID); // will return null if startFormID is null or there is no form with
        // that name, uses equalsIgnoreCase()
        if (startForm != null) project.setStartForm(startForm);
        // else: first form of project will remain the startForm

        // Resolve form relationships:
        if (relationshipToFormID != null)
          for (Entry<Relationship, String> entry : relationshipToFormID.entrySet()) {
            Relationship rel = entry.getKey();
            Form relatedForm = project.getForm(entry.getValue()); // uses equalsIgnoreCase()
            if (relatedForm == null)
              throw new SAXException(
                  "Relationship \""
                      + rel.id
                      + "\" in form \""
                      + rel.form.id
                      + "\" refers to unknown related form \""
                      + entry.getValue()
                      + "\".");
            rel.setRelatedForm(
                relatedForm); // will trigger initialisation of Schema of relatedForm (this should
            // not be a problem, it will not be done again below)
          }

        // Initialise forms...
        for (Form form : project.getForms()) {
          try {
            // generates Schema, Columns & ValueDictionaries:
            form.initialiseStorage(
                fsiProvider != null
                    ? fsiProvider.getByPassableFieldIDs(form)
                    : null); // Note: fsiProvider will be null if this project is loaded/parsed for
            // the first time
          } catch (ModelFullException mfe) {
            throw new SAXException(
                "This project contains more data-producing Forms than allowed (maximum: "
                    + Project.MAX_RECORD_PRODUCING_FORMS
                    + ").");
          } catch (DuplicateColumnException dce) {
            throw new SAXException(
                "Duplicate column name (\""
                    + dce.getColumnName()
                    + "\") in schema for form \""
                    + form.id
                    + "\".");
          }
          addWarnings(form.getWarnings()); // !!!
          form.clearWarnings();
        }
        // Seal project model:
        project.getModel().seal();

        // Resolve relationship constraints:
        if (relationshipToConstraints != null)
          for (Entry<Relationship, List<ConstraintDescription>> entry :
              relationshipToConstraints.entrySet())
            for (ConstraintDescription constrDesc : entry.getValue())
              try {
                Relationship rel = entry.getKey();
                rel.addConstraint(constrDesc.resolve(rel.getRelatedForm()));
              } catch (Exception e) {
                throw new Exception(
                    "Error upon resolving constraint on Relationship \"" + entry.getKey().id + "\"",
                    e);
              }
      }
    }
  }
Example #12
0
  @Override
  protected void parseStartElement(
      String uri, String localName, String qName, XMLAttributes attributes) throws Exception {
    try {
      // <Sapelli-Collector-Project>, or <ExCiteS-Collector-Project> (for backwards compatibility)
      if (qName.equals(TAG_PROJECT) || qName.equals(TAG_PROJECT_V1X)) {
        if (project != null) {
          addWarning("Ignoring additional " + TAG_PROJECT + " or " + TAG_PROJECT_V1X + " element.");
          return;
        }

        // Detect format version...
        int formatVersion =
            attributes.getInteger(
                ATTRIBUTE_PROJECT_FORMAT,
                qName.equals(TAG_PROJECT_V1X)
                    ? Format.v1_x.ordinal()
                    : DEFAULT_FORMAT
                        .ordinal()); // default: v1.x for ExCiteS tag, DEFAULT_FORMAT for Sapelli
        // tag.
        // 	too low:
        if (formatVersion < LOWEST_SUPPORTED_FORMAT.ordinal())
          throw new SAXException("Unsupported format version: " + formatVersion);
        // 	too high:
        else if (formatVersion
            > HIGHEST_SUPPORTED_FORMAT
                .ordinal()) { // issue warning and then try to parse as highest supported format
          // (might fail)
          addWarning(
              "Format version reported in XML file ("
                  + formatVersion
                  + ") is unsupported ("
                  + LOWEST_SUPPORTED_FORMAT
                  + " <= supported <= "
                  + HIGHEST_SUPPORTED_FORMAT
                  + "), attempting parsing with rules for version "
                  + HIGHEST_SUPPORTED_FORMAT);
          format = HIGHEST_SUPPORTED_FORMAT;
        }
        //	within range (or default because missing attribute):
        else format = Format.values()[formatVersion];

        // Project...
        project =
            new Project(
                (format == Format.v1_x)
                    ? Project.PROJECT_ID_V1X_TEMP
                    : // for format = 1 we set a temp id value (will be replaced by Form:schema-id)
                    attributes.getRequiredInteger(
                        qName,
                        ATTRIBUTE_PROJECT_ID,
                        "because format is >= 2"), // id is required for format >= 2
                attributes.getRequiredString(TAG_PROJECT, ATTRIBUTE_PROJECT_NAME, true, false),
                attributes.getString(ATTRIBUTE_PROJECT_VARIANT, null, true, false),
                attributes.getString(
                    ATTRIBUTE_PROJECT_VERSION, Project.DEFAULT_VERSION, true, false),
                fingerPrint);

        // Set default language (or "en" if not specified):
        String lang = attributes.getString(ATTRIBUTE_PROJECT_DEFAULT_LANG, null, true, false);
        project.setDefaultLanguage(lang != null ? lang : Project.DEFAULT_DEFAULT_LANGUAGE);
        if (lang == null && format == Format.v2_x)
          addWarning(
              "No valid default language has been specified for this project. Languages should be declared using the BCP-47 syntax (e.g. \"fr-CA\" for Canadian French). English (en) will be set as the default language for this project.");

        // Read startForm ID:
        startFormID = attributes.getString(ATTRIBUTE_PROJECT_START_FORM, null, true, false);

        // Add subtree parsers:
        addSubtreeParser(new ConfigurationParser(this));
        addSubtreeParser(new FormParser(this));
      }
      // <?>
      else addWarning("Ignored unrecognised or invalidly placed/repeated element <" + qName + ">.");
    } catch (Exception e) {
      e.printStackTrace(System.err);
      throw new Exception("Error while parsing element <" + qName + ">: " + e.getMessage(), e);
    }
  }