Example #1
0
  public void updateMetadata() throws SQLException, AuthorizeException {
    // Map counting number of values for each element/qualifier.
    // Keys are Strings: "element" or "element.qualifier"
    // Values are Integers indicating number of values written for a
    // element/qualifier
    Map<String, Integer> elementCount = new HashMap<String, Integer>();

    modifiedMetadata = false;

    // Arrays to store the working information required
    int[] placeNum = new int[getMetadata().size()];
    boolean[] storedDC = new boolean[getMetadata().size()];
    MetadataField[] dcFields = new MetadataField[getMetadata().size()];

    // Work out the place numbers for the in memory DC
    for (int dcIdx = 0; dcIdx < getMetadata().size(); dcIdx++) {
      DCValue dcv = getMetadata().get(dcIdx);

      // Work out the place number for ordering
      int current = 0;

      // Key into map is "element" or "element.qualifier"
      String key = dcv.element + ((dcv.qualifier == null) ? "" : ("." + dcv.qualifier));

      Integer currentInteger = elementCount.get(key);
      if (currentInteger != null) {
        current = currentInteger.intValue();
      }

      current++;
      elementCount.put(key, Integer.valueOf(current));

      // Store the calculated place number, reset the stored flag, and cache the metadatafield
      placeNum[dcIdx] = current;
      storedDC[dcIdx] = false;
      dcFields[dcIdx] = getMetadataField(dcv);
      if (dcFields[dcIdx] == null) {
        // Bad DC field, log and throw exception
        log.warn("Invalid metadata field: [" + dcv.getField() + "] : [" + dcv.value + "]");
        throw new SQLException("Invalid metadata field: [" + dcv.getField() + "]");
      }
    }

    // Now the precalculations are done, iterate through the existing metadata
    // looking for matches
    TableRowIterator tri = retrieveMetadata();
    if (tri != null) {
      try {
        while (tri.hasNext()) {
          TableRow tr = tri.next();
          // Assume that we will remove this row, unless we get a match
          boolean removeRow = true;

          // Go through the in-memory metadata, unless we've already decided to keep this row
          for (int dcIdx = 0; dcIdx < getMetadata().size() && removeRow; dcIdx++) {
            // Only process if this metadata has not already been matched to something in the DB
            if (!storedDC[dcIdx]) {
              boolean matched = true;
              DCValue dcv = getMetadata().get(dcIdx);

              // Check the metadata field is the same
              if (matched && dcFields[dcIdx].getFieldID() != tr.getIntColumn("metadata_field_id")) {
                matched = false;
              }

              // Check the place is the same
              if (matched && placeNum[dcIdx] != tr.getIntColumn("place")) {
                matched = false;
              }

              // Check the text is the same
              if (matched) {
                String text = tr.getStringColumn("text_value");
                if (dcv.value == null && text == null) {
                  matched = true;
                } else if (dcv.value != null && dcv.value.equals(text)) {
                  matched = true;
                } else {
                  matched = false;
                }
              }

              // Check the language is the same
              if (matched) {
                String lang = tr.getStringColumn("text_lang");
                if (dcv.language == null && lang == null) {
                  matched = true;
                } else if (dcv.language != null && dcv.language.equals(lang)) {
                  matched = true;
                } else {
                  matched = false;
                }
              }

              // check that authority and confidence match
              if (matched) {
                String auth = tr.getStringColumn("authority");
                int conf = tr.getIntColumn("confidence");
                if (!((dcv.authority == null && auth == null)
                    || (dcv.authority != null && auth != null && dcv.authority.equals(auth))
                        && dcv.confidence == conf)) {
                  matched = false;
                }
              }

              // If the db record is identical to the in memory values
              if (matched) {
                // Flag that the metadata is already in the DB
                storedDC[dcIdx] = true;

                // Flag that we are not going to remove the row
                removeRow = false;
              }
            }
          }

          // If after processing all the metadata values, we didn't find a match
          // delete this row from the DB
          if (removeRow) {
            DatabaseManager.delete(ourContext, tr);
            modifiedMetadata = true;
          }
        }
      } finally {
        tri.close();
      }
    }

    // Add missing in-memory DC
    for (int dcIdx = 0; dcIdx < getMetadata().size(); dcIdx++) {
      // Only write values that are not already in the db
      if (!storedDC[dcIdx]) {
        DCValue dcv = getMetadata().get(dcIdx);

        // Write DCValue
        MetadataValue metadata = new MetadataValue();
        metadata.setResourceId(getID());
        metadata.setResourceTypeId(getType());
        metadata.setFieldId(dcFields[dcIdx].getFieldID());
        metadata.setValue(dcv.value);
        metadata.setLanguage(dcv.language);
        metadata.setPlace(placeNum[dcIdx]);
        metadata.setAuthority(dcv.authority);
        metadata.setConfidence(dcv.confidence);
        metadata.create(ourContext);
        modifiedMetadata = true;
      }
    }

    if (modifiedMetadata) {
      ourContext.addEvent(
          new Event(
              Event.MODIFY_METADATA, getType(), getID(), getDetails(), getIdentifiers(ourContext)));
      modifiedMetadata = false;
    }
  }