All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opensextant.annotations.Annotation Maven / Gradle / Ivy

There is a newer version: 3.7.3
Show newest version
/*
 * IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII                  
 * 
 * OpenSextant/Xponents sub-project
 *      __                              
 *  ___/ /___  ___  ___  ___  __ __ ___ 
 * / _  // -_)/ -_)/ _ \/ -_)/ // // -_)
 * \_,_/ \__/ \__// .__/\__/ \_, / \__/ 
 *               /_/        /___/
 *               
 * IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII    
 * Copyright 2013, 2019 MITRE Corporation             
 */

package org.opensextant.annotations;

import static org.apache.commons.lang3.StringUtils.isNotBlank;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeSet;

/**
 * An annotation is at least a typed name/value pair created by something.
 * 

* Creator is called "contributor" because lots of parties can contribute annotations to this pool. *

* Every annotation belongs to some record (ident by rec_id)
* Every annotation instance has an ID itself. *

* Offset and attributes are optional, as some annotations apply to entire records, rather than data * at a certain offset. * * @author ubaldino */ public class Annotation extends DeepEyeData { public String rec_id = null; public String name = null; /** * Source ID here is very much optional Currently it is useful for SQLite usage. */ public String source_id = null; /** optional offset */ public long offset = -1; /** * optional, but recommended length. If offset is set or attrs.offsets are used, then ideally length * should be set */ private int len = 0; public String contrib = null; public Annotation() { } public Annotation(String aid) { id = aid; } public Annotation(String aid, String rid) { id = aid; rec_id = rid; } public Annotation(String aid, String rid, String ctr, String n, String v) { id = aid; rec_id = rid; contrib = ctr; name = n; value = v; if (value != null) { // Default length is based on value. this.setLength(value.length()); } } public String getAttribute(String k) { if (attrs == null) { return null; } return attrs.getString(k); } @Override public String toString() { return String.format("%s %s (Record=%s)", this.name, this.value, this.rec_id); } public void setLength(int l) { len = l; } public boolean hasLength() { return len > 0; } /** * Compute length, as logic is related to defaults, if value is set or not. etc. * * @return */ public int getLength() { if (len > 0) { return len; } if (value != null) { return value.length(); } return -1; } /** * Compute span end offset. * * @return end offset (long) */ public long getEndOffset() { int l = getLength(); if (l > 0 && offset >= 0) { return offset + l; } return -1; } /** * Add offset information (offset, len, offsets, etc ) into the representation of this annotation. * Some annotations may have a more complex view of offset, e.g., EntityAnnotation overrides this. */ protected void addOffsetTo(Map repr) { this.addOffsetAttribute(); if (this.offset >= 0) { repr.put("offset", this.offset); if (this.hasLength()) { repr.put("len", this.getLength()); } } } private TreeSet offsets = new TreeSet(); private boolean offsetsEncoded = false; public void addOffset(int x) { offsets.add(x); offsetsEncoded = false; } public Collection getOffsets() { return offsets; } /** * add annot.offset = x or annot.attrs.offsets = "x1;x2;x3"... a string list, not a JSON obj. */ public void addOffsetAttribute() { // offset attr already done. if (offsetsEncoded) { return; } if (offsets.size() > 0) { if (this.offset >= 0) { addOffset((int) this.offset); } this.newAttributes(); // Save List<>( 1, 8, 222, 456 ) as "1;8;222;456", Should the format of this optimization change, // CommonAnnotationHelper utility should help manage that. // attrs.put("offsets", AnnotationHelper.encodeOffsets(offsets)); offset = -1; offsetsEncoded = true; return; } // One value was given. // if (offset < 0 && offsets.size() == 1) { this.offset = offsets.first(); return; } } /** * This is provided mainly for testing. The EntityAnnotation class is not intended for reuse e.g., * populate an instance and then reset offsets alone. Use sparingly. */ public void resetOffsets() { offsets.clear(); offsetsEncoded = false; if (attrs != null) { this.attrs.remove("offsets"); } } /** * Generate a key-value representation of the object with its current values. * * @return Map */ @Override public Map getMap() { Map dbo = new HashMap<>(); /* * REQUIRED deepeye fields will be filled, even if value is null. */ dbo.put("_id", this.id); dbo.put("rec_id", this.rec_id); dbo.put("name", this.name); dbo.put("value", this.value); dbo.put("contrib", this.contrib); /* OPTIONAL fields attrs, source_id, etc. will appear if filled in. * */ addOffsetTo(dbo); /* * Check for NULL all the time. */ Map _attrs = this.getAttributes(); if (_attrs != null) { dbo.put("attrs", _attrs); } if (isNotBlank(this.source_id)) { dbo.put("source_id", this.source_id); } return dbo; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy