/** * The contents of this file are subject to the license and copyright * detailed in the LICENSE and NOTICE files at the root of the source * tree and available online at * * http://www.dspace.org/license/ */ package org.dspace.content; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.UUID; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; import javax.persistence.OneToMany; import javax.persistence.OrderBy; import javax.persistence.Table; import javax.persistence.Transient; import org.apache.commons.collections4.CollectionUtils; import org.dspace.authorize.ResourcePolicy; import org.dspace.core.ReloadableEntity; import org.dspace.handle.Handle; import org.hibernate.annotations.GenericGenerator; /** * Abstract base class for DSpace objects */ @Entity @Inheritance(strategy = InheritanceType.JOINED) @Table(name = "dspaceobject") public abstract class DSpaceObject implements Serializable, ReloadableEntity { @Id @GeneratedValue(generator = "system-uuid") @GenericGenerator(name = "system-uuid", strategy = "uuid2") @Column(name = "uuid", unique = true, nullable = false, insertable = true, updatable = false) protected java.util.UUID id; // accumulate information to add to "detail" element of content Event, // e.g. to document metadata fields touched, etc. @Transient private StringBuffer eventDetails = null; @OneToMany(fetch = FetchType.LAZY, mappedBy = "dSpaceObject", cascade = CascadeType.ALL, orphanRemoval = true) @OrderBy("metadataField, place") private List metadata = new ArrayList<>(); @OneToMany(fetch = FetchType.LAZY, mappedBy = "dso") // Order by is here to ensure that the oldest handle is retrieved first, // multiple handles are assigned to the latest version of an item the original handle will have the lowest // identifier // This handle is the preferred handle. @OrderBy("id ASC") private List handles = new ArrayList<>(); @OneToMany(fetch = FetchType.LAZY, mappedBy = "dSpaceObject", cascade = CascadeType.ALL) private List resourcePolicies = new ArrayList<>(); /** * True if anything else was changed since last update() * (to drive event mechanism) */ @Transient private boolean modifiedMetadata = false; /** * Flag set when data is modified, for events */ @Transient private boolean modified = false; protected DSpaceObject() { } /** * Reset the cache of event details. */ public void clearDetails() { eventDetails = null; } /** * Add a string to the cache of event details. Automatically * separates entries with a comma. * Subclass can just start calling addDetails, since it creates * the cache if it needs to. * * @param d detail string to add. */ protected void addDetails(String d) { if (eventDetails == null) { eventDetails = new StringBuffer(d); } else { eventDetails.append(", ").append(d); } } /** * @return summary of event details, or null if there are none. */ public String getDetails() { return (eventDetails == null ? null : eventDetails.toString()); } /** * Get the type of this object, found in Constants * * @return type of the object */ public abstract int getType(); /** * Get the internal ID (database primary key) of this object * * @return internal ID of object */ public UUID getID() { return id; } public abstract String getName(); /** * Get the Handle of the object. This may return null * * @return Handle of the object, or null if it doesn't have * one */ public String getHandle() { return (CollectionUtils.isNotEmpty(handles) ? handles.get(0).getHandle() : null); } void setHandle(List handle) { this.handles = handle; } public void addHandle(Handle handle) { this.handles.add(handle); } public List getHandles() { return handles; } public List getMetadata() { return metadata; } public void setMetadata(List metadata) { this.metadata = metadata; } protected void removeMetadata(MetadataValue metadataValue) { setMetadataModified(); getMetadata().remove(metadataValue); } protected void removeMetadata(List metadataValues) { setMetadataModified(); getMetadata().removeAll(metadataValues); } protected void addMetadata(MetadataValue metadataValue) { setMetadataModified(); getMetadata().add(metadataValue); addDetails(metadataValue.getMetadataField().toString()); } public List getResourcePolicies() { return resourcePolicies; } public boolean isMetadataModified() { return modifiedMetadata; } protected void setMetadataModified() { this.modifiedMetadata = true; } public boolean isModified() { return modified; } public void clearModified() { this.modified = false; } protected void setModified() { this.modified = true; } }