/** * Copyright (c) 2013 Oculus Info Inc. * http://www.oculusinfo.com/ * * Released under the MIT License. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is furnished to do * so, subject to the following conditions: * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package spimedb.cluster; import com.fasterxml.jackson.annotation.JsonIgnore; import spimedb.cluster.feature.Feature; import java.io.Serializable; import java.util.Collection; import java.util.LinkedHashMap; import java.util.Map; import java.util.UUID; /*** * Instance represents one "row" or "group" of data describing one entity in a data set. * The instances are associated with a collection of typed features that represent the data values * of the entity. Each instance can be provided a distinguishing "label" that can be used for classification. * * Each instance is assumed to be provided a unique identifier. If none is provided, then one will be generated. * * @author slangevin * */ public class Instance implements Serializable { private static final long serialVersionUID = -8781788906032267606L; protected String id; protected String classLabel; protected final Map<String, Feature> features = new LinkedHashMap<>(); public Instance() { this(UUID.randomUUID().toString()); } /*** * Constructor to specify your own id's * * NOTE: id's MUST be unique! It's is up to the caller to ensure this. * * @param id */ public Instance(String id) { this.id = id; } /*** * Return whether this Instance has the specified label * * @param label label to test * @return true if the Instance has a matching class label */ public boolean hasClassLabel(String label) { return classLabel.equalsIgnoreCase(label); } /*** * Set the class label for the Instance * @param label label to apply to the Instance */ public void setClassLabel(String label) { classLabel = label; } /*** * Return the class label given to this Instance or null if none * @return class label or null if none */ public String getClassLabel() { return classLabel; } /*** * The unique id for this Instance * @return the Instance id */ public String getId() { return id; } /*** * Set the unique Instance id * @param id id of Instance */ public void setId(String id) { this.id = id; } @Override public int hashCode() { return id.hashCode(); } @Override public String toString() { StringBuilder str = new StringBuilder(); str.append("\"id:").append(id).append("\","); int i = 1; for (Feature feature : features.values()) { str.append('"').append(feature.toString()).append('"'); if (i < features.size()) str.append(','); i++; } return str.toString(); } /*** * Add a Feature to this Instance. Features are typed data attributes that describe the Instance. * * Each Feature must have a unique id to distinguish them. * * @param feature feature to add to the Instance */ public void addFeature(Feature feature) { features.put(feature.getId(), feature); } /*** * Add a collection of Features to this Instance. Features are typed data attributes that describe the Instance. * * Each Feature must have a unique id to distinguish them. * * @param features features to add to the Instance */ public void addFeatures(Collection<? extends Feature> features) { for (Feature f : features) { addFeature(f); } } /*** * Return true if this Instance has a Feature with the specified name * @param featureName featureName to check * @return true if this Instance contain a Feature with name */ public boolean containsFeature(String featureName) { return features.containsKey(featureName); } /*** * Return the Feature with the specified name or null if the Instance doen't have a matching Feature * @param featureName name of the Feature * @return the Feature with the specified name or null if the Instance don't have a matching Feature */ public Feature getFeature(String featureName) { return features.get(featureName); } /*** * Return true if the Instance contains no Features * @return true if the Instance contains no Features */ @JsonIgnore public boolean isEmpty() { return features.isEmpty(); } /*** * Return all the Features associated with this Instance * @return collection of Features */ @JsonIgnore public Collection<Feature> getAllFeatures() { return features.values(); } /*** * Return a map of the Features associated with this Instance keyed by Feature name * @return a Map of Features */ public Map<String, Feature> getFeatures() { return features; } /*** * Add all Features in a Map to the Instance whether the Map is keyed by Feature name * @param feature Map to add */ public void setFeatures(Map<String, Feature> features) { this.features.putAll(features); } /*** * Remove the Feature with the specified name from the Instance * @param name of the Feature to remove */ public void removeFeature(String featureName) { features.remove(featureName); } /*** * Remove all the Features associated with this Instance */ public void removeAllFeatures() { features.clear(); } /*** * Return the number of Features associated with this Instance * @return the number of Features */ public int numFeatures() { return features.size(); } }