1 /**
  2  * Workflow to write metadata to an asset/assets using a REST call
  3  */
  4 
  5 var REST = library.REST.REST();
  6 var myData = {};
  7 var myFieldData = [];
  8 
  9 /**
 10  *  writes aVal to the field adds a object to myData containing the written metadata
 11  *
 12  * @param theSource -asset ID
 13  * @param theSchema
 14  * @param theField
 15  * @param theValue - value to write to the field
 16  */
 17 function setFields(theSource) {
 18   var aReturnValues = [];
 19   var aFile = fileManager.getFileObjectById(theSource);
 20   if (aFile == null) {
 21     REST.submitError(theSource, "The file does not exist");
 22     return;
 23   }
 24   for (var i = 0; i < myFieldData.length; i++) {
 25     var aFieldData = myFieldData[i];
 26 
 27     var aFieldId = aFieldData.fieldId;
 28     var aValue = aFieldData.value;
 29     var aType = aFieldData.type;
 30     var aAppend = aFieldData.append;
 31     var anAllowDuplicates = aFieldData.allowDuplicates;
 32 
 33     var aNamespaceFieldSplit = aFieldId.split(" ");
 34     var aProperty = new Property(
 35       aNamespaceFieldSplit[0],
 36       aNamespaceFieldSplit[1]
 37     );
 38     var aField = aFile.xmp.meta.getField(aProperty);
 39 
 40     if (aType === "" && !!aProperty.getFieldType()) {
 41       aType = aProperty.getFieldType();
 42     }
 43     // Change behavior based on the type specified and null-ness of the field
 44     if (aType.indexOf("list") < 0) {
 45       // The type was not specified or didn't match, so we are just going to go with our best guess.
 46       aFile.xmp.meta.addField(aProperty, aAppend ? aField + aValue : aValue);
 47       aField = aFile.xmp.meta.getField(aProperty);
 48     } else if (aField === null) {
 49       // New field with a type we want.
 50       if (aType === "Bag") {
 51         var aBag = aFile.xmp.newBag();
 52         aValue = aValue instanceof Array ? aValue : aValue.split(",");
 53         for (var j = 0; j < aValue.length; j++) {
 54           aBag.addItem(aValue[j]);
 55         }
 56         aFile.xmp.meta.addField(aProperty, aBag);
 57       } else if (
 58         !!aProperty.getFieldType() &&
 59         aProperty.getFieldType().indexOf("list") > -1
 60       ) {
 61         var aSeq = aFile.xmp.newSeq();
 62         aValue = aValue instanceof Array ? aValue : aValue.split(",");
 63         for (j = 0; j < aValue.length; j++) {
 64           aSeq.addItem(aValue[j]);
 65         }
 66         aFile.xmp.meta.addField(aProperty, aSeq);
 67       }
 68     } else if (aField !== null) {
 69       // Existing field with a possibly special type.
 70       if (aField instanceof Seq || aField instanceof Bag) {
 71         // Sequence (ordered) or Bag (unordered) container.
 72         // Clear the collection.
 73         if (!aAppend) {
 74           aField.clear();
 75         }
 76         if (!anAllowDuplicates) {
 77           var anIterator = aField.iterator;
 78           var aValues = {};
 79           while (anIterator.hasMore) {
 80             var aRemainingValue = anIterator.next;
 81             if (!!aValues[aRemainingValue]) {
 82               aValues[aRemainingValue] = true;
 83             }
 84           }
 85           aField.clear();
 86           for (var aVal in aValues) {
 87             aField.addItem(aVal);
 88           }
 89         }
 90         aValue = aValue instanceof Array ? aValue : aValue.split(",");
 91         for (j = 0; j < aValue.length; j++) {
 92           if (!anAllowDuplicates && aField.contains(aValue[j])) {
 93             continue;
 94           }
 95           aField.addItem(aValue[j]);
 96         }
 97         aFile.xmp.meta.addField(aProperty, aField);
 98       } else if (aField instanceof Alt) {
 99         // TODO for later.
100         myData.error = "Alt is not supported yet.";
101       }
102     }
103     if (aField instanceof Seq || aField instanceof Bag) {
104       try {
105         aField = JSON.parse(aField.toString());
106       } catch (anError) {
107         //failed to parse the seq or bag, just use its toString()
108         logger.info("Failed to parse: " + aFieldId + " as JSON: " + aField);
109       }
110     }
111 
112     if (aType === "string" || aType === "") {
113       if (!!aValue) {
114         aReturnValues.push(aValue);
115       }
116     } else {
117       aReturnValues.push(aField ? aField : aType + ": " + aValue);
118     }
119   }
120   if (!aFile.writeXmp()) {
121     myData.error =
122       "Failed to write to the asset: " +
123       aFile.assetId +
124       ". Ensure that the field values are allowed by the field structure";
125     return;
126   }
127   myData[theSource] = aReturnValues;
128 }
129 
130 /**
131  * Writes a new value to a field of an asset.
132  * @description Locates assets by the list of AssetID's in 'src', overwrites the field given in the 'field' parameter
133  * with the value 'value' parameter, and returns the new metadata value. These AssetIDs are parsed into a text object
134  * keyed by AssetID from the JSON file in which they are contained, and by default are displayed to the user.
135  * @example 'MBurl'/wf/restapi/1/setField?src=AssetID&fieldId='schema_name/ field_name'&value='Value'
136  * @example 'MBurl'/wf/restapi/1/setField?src=["AssetID"]&fieldId='schema_name/ field_name'&value='Value'
137  * @example 'MBurl'/wf/restapi/1/setField?src=AssetID&fieldId='schema_name/ field_name'&value=["value1", "value2", ...]&type=Bag
138  * @example <a target="_blank" href='http://127.0.0.1:55555/wf/restapi/1/setField?src=["12345"]&fieldId="http://purl.org/dc/elements/1.1/ title"&value="a new value for Dublin Core title"'>http://127.0.0.1:55555/wf/restapi/1/setField?src=["12345"]&fieldId="http://purl.org/dc/elements/1.1/ title"&value="a new value for Dublin Core title"</a>
139  * @example post parameter: "data", value:
140  * {
141 	"data" : [
142 				{"fieldId": "http://purl.org/dc/elements/1.1/ title", "value": "A new value for Dublin Core title", "type": "", "append": ""},
143 				{"fieldId": "http://purl.org/dc/elements/1.1/ description", "value": "A new value for Dublin Core description", "type": "", "append": ""}
144 			]
145 	}
146  * @class Writes a new value to a field of an asset.
147  * @name SetField
148  * @param src AssetID/list of AssetIDs of asset/assets containing field to be overwritten.
149  * @param fieldId ex http://purl.org/dc/elements/1.1/ subject
150  * @param type optional. The type of field we are writing to. If you omit it we will try to guess. If you include it
151  * only the value 'Bag' is relevant. This parameter, when ommitted and operating on a field that is a list defaults to
152  * a sequence (an ordered list).
153  * @param append  true/false.  append value to the end of the field?
154  * @returns ( {'AssetID': "New Field Value",...} )
155  */
156 function main() {
157   var aParameters = REST.getParametersToIterate("src");
158   var aDataParam = context.getParameter("data");
159   if (aDataParam != null && aDataParam != undefined) {
160     var aData = aDataParam["data"];
161     for (var i = 0; i < aData.length; i++) {
162       var aDataObject = aData[i];
163       var aType =
164         aDataObject.type != null && aDataObject.type != undefined
165           ? aDataObject.type
166           : "";
167       var aAppend =
168         aDataObject.append != null && aDataObject.append != undefined
169           ? aDataObject.append
170           : "";
171       var anAllowDuplicates =
172         aDataObject.allowDuplicates != null &&
173         aDataObject.allowDuplicates != undefined
174           ? aDataObject.allowDuplicates
175           : "";
176       myFieldData.push({
177         fieldId: aDataObject.fieldId,
178         value: aDataObject.value,
179         type: aType,
180         append: aAppend,
181         allowDuplicates: anAllowDuplicates,
182       });
183     }
184   } else {
185     var aFieldId = REST.getParameter("fieldId", true);
186     var aValue = REST.getParameter("value", true);
187     var aType = REST.getParameter("type", false);
188     var aAppend = REST.getParameter("append", false);
189     var anAllowDuplicates = REST.getParameter("allowDuplicates", false);
190     myFieldData.push({
191       fieldId: aFieldId,
192       value: aValue,
193       type: aType,
194       append: aAppend,
195       allowDuplicates: anAllowDuplicates,
196     });
197   }
198   if (myData.error != null) {
199     return REST.formatResponse();
200   }
201   REST.iterateThroughParameters(aParameters, setFields);
202   return REST.formatResponse();
203 }
204 main();
205