Skip to content

Commit

Permalink
Added support for v6 API
Browse files Browse the repository at this point in the history
  • Loading branch information
[email protected] committed Aug 29, 2019
1 parent ec06ec3 commit 427820e
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 11 deletions.
149 changes: 138 additions & 11 deletions CSV2Metadata.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.entity.StringEntity;
Expand Down Expand Up @@ -64,6 +65,7 @@ public class CSV2Metadata {
private TransformerFactory transformerFactory = TransformerFactory.newInstance();

private static final String XIP_NS = "http://www.tessella.com/XIP/v4";
private static final String XIPV6_NS = "http://preservica.com/EntityAPI/v6.0";

private Properties userDetails;

Expand Down Expand Up @@ -271,7 +273,8 @@ private int parse(File csvDocument, File folder, String filenameColumn, String r
osw.write(">");
osw.write(System.getProperty("line.separator"));

String filerefId = null;
String filerefId = null;
String assetId = null;

for (int i = 0; i < headerCount; i++) {
String header = headers[i];
Expand All @@ -289,6 +292,9 @@ private int parse(File csvDocument, File folder, String filenameColumn, String r
if (header.toLowerCase().trim().startsWith("fileref")) {
filerefId = record.get(i).trim();
}
if (header.toLowerCase().trim().startsWith("assetid")) {
assetId = record.get(i).trim();
}
}
osw.write(String.format("</%s:%s>", rootPrefix, rootElement));
osw.flush();
Expand All @@ -300,14 +306,14 @@ private int parse(File csvDocument, File folder, String filenameColumn, String r
// if the entity does not have descriptive metadata with the required
// namespace then add it.

if (filerefId != null && (filerefId.length() > 0) ) {
if (filerefId != null && (filerefId.length() > 0)) {
if ((userDetails != null) && (!userDetails.isEmpty())) {
Document xipDocument = getEntity(filerefId);
Document xipDocument = getEntityV5(filerefId);
if (xipDocument != null) {
if (!hasDublinCore(xipDocument, rootNamespace)) {
if (!hasDublinCoreV5(xipDocument, rootNamespace)) {
org.w3c.dom.Document dublinCoreDocument = getDocumentFromFile(xmlFile);
xipDocument = addDublinCore(dublinCoreDocument, xipDocument, rootNamespace);
updateEntity(xipDocument, filerefId);
xipDocument = addDublinCoreV5(dublinCoreDocument, xipDocument, rootNamespace);
updateEntityV5(xipDocument, filerefId);
} else {
System.out.println("Entity: " + filerefId + " already has Dublin Core metadata. Ignoring....");
}
Expand All @@ -319,6 +325,22 @@ private int parse(File csvDocument, File folder, String filenameColumn, String r
System.out.println("to update entries");
}
}

if (assetId != null && (assetId.length() > 0)) {
if ((userDetails != null) && (!userDetails.isEmpty())) {
Document xipDocument = getEntityV6(assetId);
if (xipDocument != null) {
if (!hasDublinCoreV6(xipDocument, rootNamespace)) {
org.w3c.dom.Document dublinCoreDocument = getDocumentFromFile(xmlFile);
updateEntityV6(dublinCoreDocument, assetId);
} else {
System.out.println("Asset: " + assetId + " already has Dublin Core metadata. Ignoring....");
}
} else {
System.out.println("Failed to find a Preservica asset with ID: " + assetId);
}
}
}
}

return numFiles;
Expand All @@ -331,7 +353,55 @@ private int parse(File csvDocument, File folder, String filenameColumn, String r
* @param document
* @param entityRef
*/
private void updateEntity(Document document, String entityRef) {
private void updateEntityV6(Document document, String entityRef) {
CloseableHttpClient client = getClient();
CloseableHttpResponse response = null;
try {

String domain = userDetails.getProperty("preservica.domain");

HttpPost postRequest = new HttpPost(String.format("https://%s/api/entity/information-objects/%s/metadata", domain, entityRef.trim()));
postRequest.setHeader("Authorization", getHeader());
postRequest.setHeader("Content-Type", "application/xml");

document.normalize();

DOMSource domSource = new DOMSource(document);
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(domSource, result);

StringEntity se = new StringEntity(writer.toString(), "UTF-8");
postRequest.setEntity(se);
response = client.execute(postRequest);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
log.info("Updated object: " + entityRef);
}
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
log.error("Failed to update entity");
log.error(response.getStatusLine().toString());
}
} catch (Exception ex) {
log.error(ex.getMessage());
throw new RuntimeException(ex);
} finally {
EntityUtils.consumeQuietly(response.getEntity());
IOUtils.closeQuietly(response);
}
return;
}



/**
* Update the Preservica File entity with the dublin core metadata
*
*
* @param document
* @param entityRef
*/
private void updateEntityV5(Document document, String entityRef) {
CloseableHttpClient client = getClient();
CloseableHttpResponse response = null;
try {
Expand Down Expand Up @@ -369,14 +439,16 @@ private void updateEntity(Document document, String entityRef) {
return;
}



/**
* Add dublin core metadata to an existing file entity
*
* @param dublinCore
* @param xipDocument
* @return Document
*/
private Document addDublinCore(Document dublinCore, Document xipDocument, String namespace) {
private Document addDublinCoreV5(Document dublinCore, Document xipDocument, String namespace) {

// Create a new Metadata element
Element metadataElement = xipDocument.createElement("Metadata");
Expand Down Expand Up @@ -414,6 +486,27 @@ private Document getDocumentFromFile(File xmlFile) {
return document;
}

private boolean hasDublinCoreV6(Document document, String namespace) {

NodeList metadataList = document.getElementsByTagNameNS(XIPV6_NS, "Metadata");
for (int i = 0; i < metadataList.getLength(); i++) {
Node metadataNode = metadataList.item(i);
NodeList fragmentList = metadataNode.getChildNodes();
for (int j = 0; j < fragmentList.getLength(); j++) {
Node fragmentNode = fragmentList.item(j);
NamedNodeMap namedNodeMap = fragmentNode.getAttributes();
if (namedNodeMap != null) {
Node attribute = namedNodeMap.getNamedItem("schema");
if (attribute != null) {
if (attribute.getNodeValue().equals(namespace)) {
return true;
}
}
}
}
}
return false;
}

/**
* Check that the current document does not have generic metadata already
Expand All @@ -424,7 +517,7 @@ private Document getDocumentFromFile(File xmlFile) {
* @param namespace
* @return true
*/
private boolean hasDublinCore(Document document, String namespace) {
private boolean hasDublinCoreV5(Document document, String namespace) {

NodeList list = document.getElementsByTagNameNS(XIP_NS, "Metadata");
for (int i = 0; i < list.getLength(); i++) {
Expand All @@ -447,13 +540,47 @@ private String getHeader() {
return String.format("Basic %s", new String(bytes, Charset.forName("UTF-8")));
}


/**
* Get a Preservica v6 asset by its asset ref
*
* @param assetRef
* @return org.w3c.dom Document of XIP XML
*/
private Document getEntityV6(String assetRef) {

String domain = userDetails.getProperty("preservica.domain");

CloseableHttpClient client = getClient();
CloseableHttpResponse response = null;
try {
HttpGet httpGet = new HttpGet(String.format("https://%s/api/entity/information-objects/%s", domain, assetRef.trim()));
httpGet.setHeader("Authorization", getHeader());
response = client.execute(httpGet);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
return getDocument(response);
}
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
log.error("Failed to create get entity");
log.error(response.getStatusLine().toString());
}
} catch (Exception ex) {
log.error(ex.getMessage());
throw new RuntimeException(ex);
} finally {
EntityUtils.consumeQuietly(response.getEntity());
IOUtils.closeQuietly(response);
}
return null;
}

/**
* Get a Preservica entity by its reference
* Get a Preservica v5 entity by its reference
*
* @param entityRef
* @return org.w3c.dom Document of XIP XML
*/
private Document getEntity(String entityRef) {
private Document getEntityV5(String entityRef) {

String domain = userDetails.getProperty("preservica.domain");

Expand Down
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ the metadata will be attached to.
Use this program if you the digital files have already been ingested into Preservica and you now want to
add additional descriptive metadata held in a spreadsheet.

For v5.x Preservica systems:

The additional column in the spreadsheet must be called "fileref" and contain the UUID of the Preservica digital file.

eg.
Expand All @@ -101,6 +103,17 @@ filename | fileref | dc:description | dc:identifier | dc:title | dc
LC-USZ62-20901.tiff | 8283edc6-8016-4100-a94c-3db90b0e4a75 | Picture of a plane | LC-USZ62-20901 | Photo Title | Plane | LOC
LC-USZ62-43601.tiff | 9183edc6-2115-2912-b8ad-5ef3013c7b21 | Picture of a Car | LC-USZ62-43601 | Photo Title2 | Car | LOC

For v6.x Preservica systems:

The additional column in the spreadsheet must be called "assetId" and contain the UUID of the Preservica digital asset.

eg.

filename | assetId | dc:description | dc:identifier | dc:title | dc:subject | dcterms:provenance
-------- | -------- | ------------- | ------------- | -------- | ----------- | -----------
LC-USZ62-20901.tiff | 8283edc6-8016-4100-a94c-3db90b0e4a75 | Picture of a plane | LC-USZ62-20901 | Photo Title | Plane | LOC
LC-USZ62-43601.tiff | 9183edc6-2115-2912-b8ad-5ef3013c7b21 | Picture of a Car | LC-USZ62-43601 | Photo Title2 | Car | LOC


To use the web service API to update metadata in Preservica you will need to create
a properties file called `preservica.properties` in the program directory
Expand Down

0 comments on commit 427820e

Please sign in to comment.