DecomposedSession.java
package emissary.parser;
import emissary.core.IBaseDataObject;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
/**
* Representation of a fully built session with metadata, header, footer, classification, initial forms, and data
*/
public class DecomposedSession {
// Serializable
static final long serialVersionUID = 8714610712515636160L;
// Keys for the decomposed session map
static final String HEADER_KEY = "HEADER";
static final String FOOTER_KEY = "FOOTER";
static final String DATA_KEY = "DATA";
static final String CLASSIFICATION_KEY = "CLASSIFICATION";
static final String METADATA_KEY = "METADATA";
static final String INITIAL_FORMS = "INITIAL_FORMS";
@Nullable
protected byte[] header = null;
@Nullable
protected byte[] footer = null;
@Nullable
protected byte[] data = null;
@Nullable
protected String classification = null;
protected List<String> initialForms = new ArrayList<>();
protected ArrayListMultimap<String, Object> metadata = ArrayListMultimap.create(100, 1);
/**
* Set the header. This implementation does NOT make a copy of the byte array Previously existing header data is lost
*
* @param h byte array of header data to set
*/
public void setHeader(byte[] h) {
header = h;
}
/**
* Get the header
*
* @return byte array of header data or null if none
*/
public byte[] getHeader() {
return header;
}
/**
* Set the footer This implementation does NOT make a copy of the byte array Previously existing footer data is lost
*
* @param f byte array of data to set as footer
*/
public void setFooter(byte[] f) {
footer = f;
}
/**
* Get the footer
*
* @return byte array of footer or null if none
*/
public byte[] getFooter() {
return footer;
}
/**
* Set the data entry using the passed in byte array This implementation does NOT make a copy of the byte array
* Previously existing data is lost
*
* @param d bytes to set
*/
public void setData(byte[] d) {
setData(d, false);
}
/**
* Set the data entry using the passed in byte array or a copy Previously existing data is lost
*
* @param d bytes to set
* @param copy make a copy when true
*/
public void setData(@Nullable byte[] d, boolean copy) {
if (d == null || !copy) {
data = d;
} else {
setData(d, 0, d.length);
}
}
/**
* Set the data from the specified portion of the array Always makes a copy. Previously existing data is lost.
*
* @param d bytes to set
* @param start start offset
* @param end ending offset
*/
public void setData(byte[] d, int start, int end) {
data = new byte[end - start];
System.arraycopy(d, start, data, 0, data.length);
}
/**
* Get the data entry
*
* @return the data bytes or null if none
*/
public byte[] getData() {
return data;
}
/**
* Set the classification
*
* @param s the value to set
*/
public void setClassification(String s) {
classification = s;
}
/**
* Get the classification
*
* @return the classification entry or null if none
*/
public String getClassification() {
return classification;
}
/**
* Add metadata from map, any existing is lost
*
* @param m the map of metadata to set
*/
public void setMetaData(Map<String, ?> m) {
metadata.clear();
addMetaData(m);
}
/**
* Return the metadata map, creating one if it doesnt exist already
*
* @return the map of MetaData
*/
public Map<String, Collection<Object>> getMetaData() {
return metadata.asMap();
}
/**
* Return the entire multimap of metadata for use during the construction process
*/
public Multimap<String, Object> getMultimap() {
return metadata;
}
/**
* Test for header presence
*
* @return true if there is a header entry
*/
public boolean hasHeader() {
return header != null;
}
/**
* Test for footer presence
*
* @return true if there is a footer entry
*/
public boolean hasFooter() {
return footer != null;
}
/**
* Test for classification presence
*
* @return true if there is a classification entry
*/
public boolean hasClassification() {
return classification != null;
}
/**
* Test for metadata presence
*
* @return true if there is a metadata entry
*/
public boolean hasMetaData() {
return metadata.size() > 0;
}
/**
* Test for data presence
*
* @return true if there is a data entry
*/
public boolean hasData() {
return data != null;
}
/**
* Add a record to the nested MetaData map Metadata map will be created if not existing
*
* @param name the name of the meta record to add
* @param value the value to add
*/
public void addMetaData(@Nullable String name, @Nullable Object value) {
if (name != null && value != null) {
metadata.put(name, value);
}
}
/**
* Add a map of metadata to the existing map MetaData map will be created if not existing
*
* @param m map of items to add
*/
public void addMetaData(@Nullable Map<String, ?> m) {
if (m != null && m.size() > 0) {
for (Map.Entry<String, ?> entry : m.entrySet()) {
String key = entry.getKey();
Object v = entry.getValue();
if (v instanceof Iterable) {
metadata.putAll(key, (Iterable<?>) v);
} else {
metadata.put(key, v);
}
}
}
}
/**
* Return a single metadata item
*
* @param key the name
*/
public List<Object> getMetaDataItem(String key) {
return metadata.get(key);
}
/**
* Get a simplified form of a single metadata item using semi-colon as the separator
*
* @param key the name
*/
public String getStringMetadataItem(String key) {
return getStringMetadataItem(key, IBaseDataObject.DEFAULT_PARAM_SEPARATOR);
}
/**
* Get a simplified form of a single metadata item
*
* @param key the name
* @param sep the separator
*/
@Nullable
public String getStringMetadataItem(String key, String sep) {
List<Object> o = metadata.get(key);
if (o.isEmpty()) {
return null;
}
StringBuilder sb = new StringBuilder();
for (Object item : o) {
if (sb.length() > 0) {
sb.append(sep);
}
sb.append(item);
}
return sb.toString();
}
/**
* Add an initial form to the list of existing forms. Initial forms will be created if not existing
*
* @param form initial form to add
*/
public void addInitialForm(@Nullable String form) {
if (form != null) {
initialForms.add(form);
}
}
/**
* Set the list of initial forms to use This will overwrite existing initial forms
*/
public void setInitialForms(@Nullable List<String> forms) {
if (forms != null) {
initialForms = new ArrayList<>(forms);
}
}
/**
* Get the list of initial forms. Returns empty list if no initial forms have been set
*/
public List<String> getInitialForms() {
return initialForms;
}
/**
* Check validity of session
*/
public boolean isValid() {
return hasData() || hasHeader() || hasFooter();
}
}