/** * $Id: EntityData.java 105077 2012-02-24 22:54:29Z ottenhoff@longsight.com $ * $URL: https://source.sakaiproject.org/svn/entitybroker/trunk/api/src/java/org/sakaiproject/entitybroker/entityprovider/extension/EntityData.java $ * EntityData.java - entity-broker - Aug 3, 2008 6:03:53 PM - azeckoski ************************************************************************** * Copyright (c) 2008 The Sakai Foundation * * Licensed under the Educational Community 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.opensource.org/licenses/ECL-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.sakaiproject.entitybroker.entityprovider.extension; import java.io.Serializable; import java.util.Comparator; import java.util.HashMap; import java.util.Map; import org.sakaiproject.entitybroker.EntityReference; import org.sakaiproject.entitybroker.EntityView; import org.sakaiproject.entitybroker.entityprovider.capabilities.Resolvable; /** * This is an object to hold entity data (e.g. from a search which would normally return entity references), * This is basically a POJO which allows us to return a few results instead of only the reference, * it helps us get the entity data back more efficiently and makes it easier on developers who * need to search for entities * * @author Aaron Zeckoski (azeckoski @ gmail.com) */ public class EntityData { /** * (OPTIONAL - may be null) * This is the entity data object itself (if there is one), * this is included at the discretion of the entity provider author, * if this is null then the entity data is not available or would be prohibitively large (i.e. typically left out for efficiency) */ private Object data; public void setData(Object entity) { this.data = entity; // if (data != null) { // this.entity = new WeakReference<Object>(data); // } else { // this.entity = null; // } } /** * (OPTIONAL - may be null) * This is the entity data object itself (if there is one), * this is included at the discretion of the entity provider author, * if this is null then the entity data is not available or would be prohibitively large (i.e. typically left out for efficiency) */ public Object getData() { return this.data; // if (this.entity == null) { // return null; // } else { // return this.entity.get(); // } } private String entityId = null; /** * @return the unique local id of the entity (null if there is none) */ public String getEntityId() { return entityId; } /** * The entity reference - a globally unique reference to an entity, * consists of the entity prefix and optional segments (normally the id at least), * this should be set by the constructor only */ private String entityReference; /** * The entity reference - a globally unique reference to an entity, * consists of the entity prefix and optional segments (normally the id at least) */ public String getEntityReference() { return entityReference; } /** * The entity reference object which makes it easy to get to the prefix or id of this entity, * this should be set by the constructor only */ private transient EntityReference entityRef; /** * The entity reference object which makes it easy to get to the prefix or id of this entity if needed */ public EntityReference getEntityRef() { return entityRef; } /** * A string which is suitable for display and provides a short summary of the entity, * typically 100 chars or less, this may be the name or title of the data represented by an entity */ private String entityDisplayTitle; /** * A string which is suitable for display and provides a short summary of the entity, * typically 100 chars or less, this may be the name or title of the data represented by an entity */ public void setDisplayTitle(String displayTitle) { this.entityDisplayTitle = displayTitle; } /** * A string which is suitable for display and provides a short summary of the entity, * typically 100 chars or less, this may be the name or title of the data represented by an entity */ public String getDisplayTitle() { if (this.entityDisplayTitle == null) { if (this.entityRef != null) { return this.entityRef.getPrefix() + " : " + entityReference; } else { return "data"; } } return entityDisplayTitle; } private transient boolean displayTitleSet = false; // needed to avoid encoding /** * @return true if the display title is actually set, false if it is null and will return an auto-generated value */ public boolean isDisplayTitleSet() { displayTitleSet = entityDisplayTitle != null; return displayTitleSet; } /** * (OPTIONAL - may be null) * The entityURL to the entity represented by this reference, * should be an absolute entityURL (server name optional), * if this is null then the entityURL is formed from the reference */ private String entityURL; /** * WARNING: for internal use only * @param url the url to access this entity */ public void setEntityURL(String url) { entityURL = url; } /** * The entityURL to the entity represented by this reference, * should be an absolute entityURL (server name optional) */ public String getEntityURL() { return entityURL; } /** * (OPTIONAL - may be null) * A set of properties to return along with the entity information, * this may be presented and used for filtering, * this will be null or empty if it is not used */ private Map<String, Object> entityProperties; /** * (OPTIONAL - may be null) * A set of properties to return along with the entity information, * this may be presented and used for filtering, * should be null or empty if not used * @param entityProperties a map of property name => value */ public void setEntityProperties(Map<String, Object> entityProperties) { this.entityProperties = entityProperties; } /** * A set of properties to return along with the entity information, * this may be presented and used for filtering, * this will be empty if it is not used */ public Map<String, Object> getEntityProperties() { if (entityProperties == null) { entityProperties = new HashMap<String, Object>(0); } return entityProperties; } /** * used to ensure that we do not accidently attempt to populate this twice */ private transient boolean populated = false; /** * FOR INTERNAL USE ONLY - do not use */ public void setPopulated(boolean populated) { this.populated = populated; } /** * @return true if this object was populated, false otherwise */ public boolean isPopulated() { return populated; } /** * indicates that this is a holder and should be discarded and the data * rendered into the given format without it */ private transient boolean dataOnly = false; /** * FOR INTERNAL USE ONLY - do not use */ public void setDataOnly(boolean dataOnly) { this.dataOnly = dataOnly; } /** * @return true if this is a data holder and the data inside it should be rendered alone without this wrapper */ public boolean isDataOnly() { return dataOnly; } /** * Minimal constructor - used for most basic cases<br/> * Use the setters to add in properties or the entity if desired * * @param reference a globally unique reference to an entity, * consists of the entity prefix and id (e.g. /prefix/id) * @param entityDisplayTitle a string which is suitable for display and provides a short summary of the entity, * typically 100 chars or less, this may be the name or title of the entity represented by an entity */ public EntityData(String reference, String displayTitle) { this(reference, displayTitle, null, null); } /** * Basic constructor<br/> * Use this to construct a search result using the typical minimal amount of information, * Use the setters to add in properties or the entity if desired * * @param reference a globally unique reference to an entity, * consists of the entity prefix and id (e.g. /prefix/id) * @param entityDisplayTitle a string which is suitable for display and provides a short summary of the entity, * typically 100 chars or less, this may be the name or title of the entity represented by an entity * @param data an entity data object, see {@link Resolvable} */ public EntityData(String reference, String displayTitle, Object entity) { this(reference, displayTitle, entity, null); } /** * Full constructor<br/> * Use this if you want to return the entity itself along with the key meta data and properties * * @param reference a globally unique reference to an entity, * consists of the entity prefix and id (e.g. /prefix/id) * @param entityDisplayTitle a string which is suitable for display and provides a short summary of the entity, * typically 100 chars or less, this may be the name or title of the entity represented by an entity * @param data an entity data object, see {@link Resolvable} * @param entityProperties a set of properties to return along with the entity information, * this may be presented and used for filtering, */ public EntityData(String reference, String displayTitle, Object entity, Map<String, Object> entityProperties) { this.entityRef = new EntityReference(reference); this.entityReference = this.entityRef.getReference(); this.entityId = this.entityRef.getId(); this.entityDisplayTitle = displayTitle; this.entityURL = EntityView.DIRECT_PREFIX + this.entityReference; setData(entity); setEntityProperties(entityProperties); } /** * Minimal constructor - used for most basic cases<br/> * Use the setters to add in properties or the entity data if desired * * @param ref an object which represents a globally unique reference to an entity, * consists of the entity prefix and id * @param entityDisplayTitle a string which is suitable for display and provides a short summary of the entity, * typically 100 chars or less, this may be the name or title of the entity represented by an entity */ public EntityData(EntityReference ref, String displayTitle) { this(ref, displayTitle, null, null); } /** * Basic constructor<br/> * Use this to construct a search result using the typical minimal amount of information, * Use the setters to add in properties or the entity data if desired * * @param ref an object which represents a globally unique reference to an entity, * consists of the entity prefix and id * @param entityDisplayTitle a string which is suitable for display and provides a short summary of the entity, * typically 100 chars or less, this may be the name or title of the entity represented by an entity * @param data an entity data object, see {@link Resolvable} */ public EntityData(EntityReference ref, String displayTitle, Object entity) { this(ref, displayTitle, entity, null); } /** * Full constructor<br/> * Use this if you want to return the entity itself along with the key meta data and properties * * @param ref an object which represents a globally unique reference to an entity, * consists of the entity prefix and id * @param entityDisplayTitle a string which is suitable for display and provides a short summary of the entity, * typically 100 chars or less, this may be the name or title of the entity represented by an entity * @param data an entity data object, see {@link Resolvable} * @param entityProperties a set of properties to return along with the entity information, * this may be presented and used for filtering, */ public EntityData(EntityReference ref, String displayTitle, Object entity, Map<String, Object> entityProperties) { if (ref == null || ref.isEmpty()) { throw new IllegalArgumentException("reference object cannot be null and must have values set"); } this.entityRef = ref; this.entityReference = this.entityRef.getReference(); this.entityId = this.entityRef.getId(); this.entityDisplayTitle = displayTitle; this.entityURL = EntityView.DIRECT_PREFIX + this.entityReference; this.entityDisplayTitle = displayTitle; setData(entity); setEntityProperties(entityProperties); } /** * Using this as a data wrapper only * @param data any data to wrap this in */ public EntityData(Object data) { this(data, null); } /** * Using this as a data wrapper only * @param data any data to wrap this in * @param entityProperties a set of properties to return along with the entity information, * this may be presented and used for filtering, */ public EntityData(Object data, Map<String, Object> entityProperties) { setData(data); setEntityProperties(entityProperties); this.dataOnly = true; } @Override public boolean equals(Object obj) { if (null == obj) return false; if (!(obj instanceof EntityData)) return false; else { EntityData castObj = (EntityData) obj; if (null == this.entityReference || null == castObj.entityReference) return false; else return (this.entityReference.equals(castObj.entityReference)); } } @Override public int hashCode() { String hashStr = this.getClass().getName() + ":" + this.entityReference.hashCode(); return hashStr.hashCode(); } @Override public String toString() { return "ED: ref="+entityReference+":display="+entityDisplayTitle+":url="+entityURL+":props("+getEntityProperties().size()+"):dataOnly="+dataOnly+":data="+data; } public static class ReferenceComparator implements Comparator<EntityData>, Serializable { public final static long serialVersionUID = 1l; public int compare(EntityData o1, EntityData o2) { return o1.entityReference.compareTo(o2.entityReference); } } public static class TitleComparator implements Comparator<EntityData>, Serializable { public final static long serialVersionUID = 1l; public int compare(EntityData o1, EntityData o2) { return o1.getDisplayTitle().compareTo(o2.getDisplayTitle()); } } }