/* Copyright 2014 MITRE Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.mitre.provenance;
import java.io.PrintStream;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;
/**
* A metadata object is a simple lookup table of key/value pairs.
* Metadata objects are tagged to all PLUSObjects, allowing you to associate arbitrary extra information
* with an object regardless of type.
*
* <p>Provenance objects contain base metadata which applies to all sorts of things you might want to log
* provenance about, but Metadata provides an "escape hatch" of sorts where you can apply any kind of
* arbitrary system-specific metadata to a provenance object. This class implements that feature.
* @author moxious
*/
public class Metadata extends java.util.Hashtable <String,Object> {
public static final long serialVersionUID = 131324134;
/** The maximum size of a key permitted. This must be limited to prevent storage-layer problems */
public static final int MAX_KEY_SIZE = 128;
/** The maximum size of a value permitted. This must be limited to prevent storage-layer problems. */
public static final int MAX_VALUE_SIZE = 16 * 1024; // 16KB.
/**
* This key is to be used to store SHA-256 content hashes of the data the provenance refers to.
* Normally, we'll expect that the value behind this key is something that came from PLUS content
* hashing tools. That is, the value should be UTF-8 text containing LOWERCASE base64 text describing the
* hash. For example, the correct SHA256 hash of the string "Hello, World!" is:
* dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f
*
* @see org.mitre.provenance.contenthash.ContentHasher#formatAsHexString(byte[])
*/
public static final String CONTENT_HASH_SHA_256 = "sha256hash";
/** Value that tracks which PLUSObject owns this metadata. This value is only set if/when writeToDB()
* is called.
*/
String ownerOID = null;
public Metadata() {
super();
setOwnerOID(null);
}
/**
* Copy the contents of another map into this metadata object.
* @param other a map containing keys and values to be copied.
*/
public void copy(Map <String, Object> other) {
if(other == null) return;
Iterator <String> it = other.keySet().iterator();
while(it.hasNext()) {
String key = it.next();
put(""+key, other.get(key));
} // End while
} // End copy
public Object put(String key, Number val) { return put(key, ""+val); }
public boolean equals(Object other) {
if(!(other instanceof Metadata)) return false;
return super.equals(other);
}
/**
* Put a key and value into the Metadata object.
* @param key the key
* @param val the value
* @see java.util.Hashtable#put(Object, Object)
*/
public Object put(String key, String val) {
// Append blank text to val, so that if it's null,
// you'll get the string null. Otherwise, null val will
// cause an exception, which isn't desirable here.
Object result = super.put(key, ""+val);
return result;
} // End put
public String getOwnerOID() { return ownerOID; }
public void setOwnerOID(String ownerOID) { this.ownerOID = ownerOID; }
public void dump(PrintStream output) throws Exception {
output.println("METADATA:");
Enumeration <String> keys = keys();
while(keys.hasMoreElements()) {
String e = keys.nextElement();
output.println(e + " = " + get(e));
} // End while
} // End dump
} // End Metadata