mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-14 13:33:08 +00:00
DSpace refactored service api
This commit is contained in:
@@ -7,24 +7,9 @@
|
||||
*/
|
||||
package org.dspace.content;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.hibernate.proxy.HibernateProxyHelper;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.authorize.AuthorizeManager;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.core.LogManager;
|
||||
import org.dspace.storage.rdbms.DatabaseManager;
|
||||
import org.dspace.storage.rdbms.TableRow;
|
||||
import org.dspace.storage.rdbms.TableRowIterator;
|
||||
import javax.persistence.*;
|
||||
|
||||
/**
|
||||
* DSpace object that represents a metadata field, which is
|
||||
@@ -36,96 +21,44 @@ import org.dspace.storage.rdbms.TableRowIterator;
|
||||
* @see org.dspace.content.MetadataValue
|
||||
* @see org.dspace.content.MetadataSchema
|
||||
*/
|
||||
public class MetadataField
|
||||
{
|
||||
private int fieldID = 0;
|
||||
private int schemaID = 0;
|
||||
@Entity
|
||||
@Table(name="metadatafieldregistry", schema = "public")
|
||||
public class MetadataField {
|
||||
|
||||
@Id
|
||||
@Column(name="metadata_field_id", nullable = false, unique = true)
|
||||
@GeneratedValue(strategy = GenerationType.SEQUENCE ,generator="metadatafieldregistry_seq")
|
||||
@SequenceGenerator(name="metadatafieldregistry_seq", sequenceName="metadatafieldregistry_seq", allocationSize = 1, initialValue = 1)
|
||||
private int id;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "metadata_schema_id",nullable = false)
|
||||
private MetadataSchema metadataSchema;
|
||||
|
||||
@Column(name = "element", length = 64)
|
||||
private String element;
|
||||
private String qualifier;
|
||||
|
||||
@Column(name = "qualifier", length = 64)
|
||||
private String qualifier = null;
|
||||
|
||||
// @Column(name = "scope_note")
|
||||
// @Lob
|
||||
@Column(name="scope_note", columnDefinition = "text")
|
||||
private String scopeNote;
|
||||
|
||||
/** log4j logger */
|
||||
private static Logger log = Logger.getLogger(MetadataField.class);
|
||||
|
||||
/** The row in the table representing this type */
|
||||
private TableRow row;
|
||||
|
||||
// cache of field by ID (Integer)
|
||||
private static Map<Integer, MetadataField> id2field = null;
|
||||
|
||||
/** metadatafield cache */
|
||||
private static Map<String, MetadataField> metadatafieldcache = null;
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
public MetadataField()
|
||||
protected MetadataField()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor creating a field within a schema.
|
||||
* Get the metadata field id.
|
||||
*
|
||||
* @param schema schema to which the field belongs
|
||||
* @return metadata field id
|
||||
*/
|
||||
public MetadataField(MetadataSchema schema)
|
||||
public int getFieldID()
|
||||
{
|
||||
this.schemaID = schema.getSchemaID();
|
||||
}
|
||||
|
||||
/**
|
||||
* Full constructor for new metadata field elements.
|
||||
*
|
||||
* @param schema schema to which the field belongs
|
||||
* @param element element of the field
|
||||
* @param qualifier qualifier of the field
|
||||
* @param scopeNote scope note of the field
|
||||
*/
|
||||
public MetadataField(MetadataSchema schema, String element,
|
||||
String qualifier, String scopeNote)
|
||||
{
|
||||
this.schemaID = schema.getSchemaID();
|
||||
this.element = element;
|
||||
this.qualifier = qualifier;
|
||||
this.scopeNote = scopeNote;
|
||||
}
|
||||
|
||||
/**
|
||||
* Full constructor for existing metadata field elements.
|
||||
*
|
||||
* @param schemaID schema to which the field belongs
|
||||
* @param fieldID database ID of field.
|
||||
* @param element element of the field
|
||||
* @param qualifier qualifier of the field
|
||||
* @param scopeNote scope note of the field
|
||||
*/
|
||||
public MetadataField(int schemaID, int fieldID, String element,
|
||||
String qualifier, String scopeNote)
|
||||
{
|
||||
this.schemaID = schemaID;
|
||||
this.fieldID = fieldID;
|
||||
this.element = element;
|
||||
this.qualifier = qualifier;
|
||||
this.scopeNote = scopeNote;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor to load the object from the database.
|
||||
*
|
||||
* @param row database row from which to populate object.
|
||||
*/
|
||||
public MetadataField(TableRow row)
|
||||
{
|
||||
if (row != null)
|
||||
{
|
||||
this.fieldID = row.getIntColumn("metadata_field_id");
|
||||
this.schemaID = row.getIntColumn("metadata_schema_id");
|
||||
this.element = row.getStringColumn("element");
|
||||
this.qualifier = row.getStringColumn("qualifier");
|
||||
this.scopeNote = row.getStringColumn("scope_note");
|
||||
this.row = row;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -148,16 +81,6 @@ public class MetadataField
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the metadata field id.
|
||||
*
|
||||
* @return metadata field id
|
||||
*/
|
||||
public int getFieldID()
|
||||
{
|
||||
return fieldID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the qualifier.
|
||||
*
|
||||
@@ -178,26 +101,6 @@ public class MetadataField
|
||||
this.qualifier = qualifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the schema record key.
|
||||
*
|
||||
* @return schema record key
|
||||
*/
|
||||
public int getSchemaID()
|
||||
{
|
||||
return schemaID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the schema record key.
|
||||
*
|
||||
* @param schemaID new value for key
|
||||
*/
|
||||
public void setSchemaID(int schemaID)
|
||||
{
|
||||
this.schemaID = schemaID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the scope note.
|
||||
*
|
||||
@@ -219,419 +122,24 @@ public class MetadataField
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new metadata field.
|
||||
* Get the schema .
|
||||
*
|
||||
* @param context
|
||||
* DSpace context object
|
||||
* @throws IOException
|
||||
* @throws AuthorizeException
|
||||
* @throws SQLException
|
||||
* @throws NonUniqueMetadataException
|
||||
* @return schema record
|
||||
*/
|
||||
public void create(Context context) throws IOException, AuthorizeException,
|
||||
SQLException, NonUniqueMetadataException
|
||||
{
|
||||
// Check authorisation: Only admins may create DC types
|
||||
if (!AuthorizeManager.isAdmin(context))
|
||||
{
|
||||
throw new AuthorizeException(
|
||||
"Only administrators may modify the metadata registry");
|
||||
}
|
||||
|
||||
// Ensure the element and qualifier are unique within a given schema.
|
||||
if (!unique(context, schemaID, element, qualifier))
|
||||
{
|
||||
throw new NonUniqueMetadataException("Please make " + element + "."
|
||||
+ qualifier + " unique within schema #" + schemaID);
|
||||
}
|
||||
|
||||
// Create a table row and update it with the values
|
||||
row = DatabaseManager.row("MetadataFieldRegistry");
|
||||
row.setColumn("metadata_schema_id", schemaID);
|
||||
row.setColumn("element", element);
|
||||
row.setColumn("qualifier", qualifier);
|
||||
row.setColumn("scope_note", scopeNote);
|
||||
DatabaseManager.insert(context, row);
|
||||
decache();
|
||||
|
||||
// Remember the new row number
|
||||
this.fieldID = row.getIntColumn("metadata_field_id");
|
||||
|
||||
log.info(LogManager.getHeader(context, "create_metadata_field",
|
||||
"metadata_field_id=" + row.getIntColumn("metadata_field_id")));
|
||||
public MetadataSchema getMetadataSchema() {
|
||||
return metadataSchema;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the metadata field from the database.
|
||||
* Set the schema record key.
|
||||
*
|
||||
* @param context dspace context
|
||||
* @param schemaID schema by ID
|
||||
* @param element element name
|
||||
* @param qualifier qualifier (may be ANY or null)
|
||||
* @return recalled metadata field
|
||||
* @throws SQLException
|
||||
* @throws AuthorizeException
|
||||
* @param metadataSchema new value for key
|
||||
*/
|
||||
public static MetadataField findByElement(Context context, int schemaID,
|
||||
String element, String qualifier) throws SQLException
|
||||
{
|
||||
|
||||
if (!isCacheInitialized()){
|
||||
initCache(context);
|
||||
}
|
||||
|
||||
// 'sanity check' first.
|
||||
String metadataFieldKey = schemaID+"."+element+"."+qualifier;
|
||||
if(!metadatafieldcache.containsKey(metadataFieldKey)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return metadatafieldcache.get(metadataFieldKey);
|
||||
public void setMetadataSchema(MetadataSchema metadataSchema) {
|
||||
this.metadataSchema = metadataSchema;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all Dublin Core types from the registry
|
||||
*
|
||||
* @param context dspace context
|
||||
* @return an array of all the Dublin Core types
|
||||
* @throws SQLException
|
||||
*/
|
||||
public static MetadataField[] findAll(Context context) throws SQLException
|
||||
{
|
||||
List<MetadataField> fields = new ArrayList<MetadataField>();
|
||||
|
||||
// Get all the metadatafieldregistry rows
|
||||
TableRowIterator tri = DatabaseManager.queryTable(context, "MetadataFieldRegistry",
|
||||
"SELECT mfr.* FROM MetadataFieldRegistry mfr, MetadataSchemaRegistry msr where mfr.metadata_schema_id= msr.metadata_schema_id ORDER BY msr.short_id, mfr.element, mfr.qualifier");
|
||||
|
||||
try
|
||||
{
|
||||
// Make into DC Type objects
|
||||
while (tri.hasNext())
|
||||
{
|
||||
fields.add(new MetadataField(tri.next()));
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
// close the TableRowIterator to free up resources
|
||||
if (tri != null)
|
||||
{
|
||||
tri.close();
|
||||
}
|
||||
}
|
||||
|
||||
// Convert list into an array
|
||||
MetadataField[] typeArray = new MetadataField[fields.size()];
|
||||
return (MetadataField[]) fields.toArray(typeArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all metadata fields that are found in a given schema.
|
||||
*
|
||||
* @param context dspace context
|
||||
* @param schemaID schema by db ID
|
||||
* @return array of metadata fields
|
||||
* @throws SQLException
|
||||
*/
|
||||
public static MetadataField[] findAllInSchema(Context context, int schemaID)
|
||||
throws SQLException
|
||||
{
|
||||
List<MetadataField> fields = new ArrayList<MetadataField>();
|
||||
|
||||
// Get all the metadatafieldregistry rows
|
||||
TableRowIterator tri = DatabaseManager.queryTable(context,"MetadataFieldRegistry",
|
||||
"SELECT * FROM MetadataFieldRegistry WHERE metadata_schema_id= ? " +
|
||||
" ORDER BY element, qualifier", schemaID);
|
||||
|
||||
try
|
||||
{
|
||||
// Make into DC Type objects
|
||||
while (tri.hasNext())
|
||||
{
|
||||
fields.add(new MetadataField(tri.next()));
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
// close the TableRowIterator to free up resources
|
||||
if (tri != null)
|
||||
{
|
||||
tri.close();
|
||||
}
|
||||
}
|
||||
|
||||
// Convert list into an array
|
||||
MetadataField[] typeArray = new MetadataField[fields.size()];
|
||||
return (MetadataField[]) fields.toArray(typeArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the metadata field in the database.
|
||||
*
|
||||
* @param context dspace context
|
||||
* @throws SQLException
|
||||
* @throws AuthorizeException
|
||||
* @throws NonUniqueMetadataException
|
||||
* @throws IOException
|
||||
*/
|
||||
public void update(Context context) throws SQLException,
|
||||
AuthorizeException, NonUniqueMetadataException, IOException
|
||||
{
|
||||
// Check authorisation: Only admins may update the metadata registry
|
||||
if (!AuthorizeManager.isAdmin(context))
|
||||
{
|
||||
throw new AuthorizeException(
|
||||
"Only administrators may modiffy the Dublin Core registry");
|
||||
}
|
||||
|
||||
// Check to see if the schema ID was altered. If is was then we will
|
||||
// query to ensure that there is not already a duplicate name field.
|
||||
if (row.getIntColumn("metadata_schema_id") != schemaID)
|
||||
{
|
||||
if (MetadataField.hasElement(context, schemaID, element, qualifier))
|
||||
{
|
||||
throw new NonUniqueMetadataException(
|
||||
"Duplcate field name found in target schema");
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure the element and qualifier are unique within a given schema.
|
||||
if (!unique(context, schemaID, element, qualifier))
|
||||
{
|
||||
throw new NonUniqueMetadataException("Please make " + element + "."
|
||||
+ qualifier);
|
||||
}
|
||||
|
||||
row.setColumn("metadata_schema_id", schemaID);
|
||||
row.setColumn("element", element);
|
||||
row.setColumn("qualifier", qualifier);
|
||||
row.setColumn("scope_note", scopeNote);
|
||||
DatabaseManager.update(context, row);
|
||||
decache();
|
||||
|
||||
log.info(LogManager.getHeader(context, "update_metadatafieldregistry",
|
||||
"metadata_field_id=" + getFieldID() + "element=" + getElement()
|
||||
+ "qualifier=" + getQualifier()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if and only if the schema has a field with the given element
|
||||
* and qualifier pair.
|
||||
*
|
||||
* @param context dspace context
|
||||
* @param schemaID schema by ID
|
||||
* @param element element name
|
||||
* @param qualifier qualifier name
|
||||
* @return true if the field exists
|
||||
* @throws SQLException
|
||||
* @throws AuthorizeException
|
||||
*/
|
||||
private static boolean hasElement(Context context, int schemaID,
|
||||
String element, String qualifier) throws SQLException,
|
||||
AuthorizeException
|
||||
{
|
||||
return MetadataField.findByElement(context, schemaID, element,
|
||||
qualifier) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the metadata field.
|
||||
*
|
||||
* @param context dspace context
|
||||
* @throws SQLException
|
||||
* @throws AuthorizeException
|
||||
*/
|
||||
public void delete(Context context) throws SQLException, AuthorizeException
|
||||
{
|
||||
// Check authorisation: Only admins may create DC types
|
||||
if (!AuthorizeManager.isAdmin(context))
|
||||
{
|
||||
throw new AuthorizeException(
|
||||
"Only administrators may modify the metadata registry");
|
||||
}
|
||||
|
||||
log.info(LogManager.getHeader(context, "delete_metadata_field",
|
||||
"metadata_field_id=" + getFieldID()));
|
||||
|
||||
DatabaseManager.delete(context, row);
|
||||
decache();
|
||||
}
|
||||
|
||||
/**
|
||||
* A sanity check that ensures a given element and qualifier are unique
|
||||
* within a given schema. The check happens in code as we cannot use a
|
||||
* database constraint.
|
||||
*
|
||||
* @param context dspace context
|
||||
* @param schemaID
|
||||
* @param element
|
||||
* @param qualifier
|
||||
* @return true if unique
|
||||
* @throws AuthorizeException
|
||||
* @throws SQLException
|
||||
* @throws IOException
|
||||
*/
|
||||
private boolean unique(Context context, int schemaID, String element,
|
||||
String qualifier) throws IOException, SQLException,
|
||||
AuthorizeException
|
||||
{
|
||||
int count = 0;
|
||||
Connection con = null;
|
||||
PreparedStatement statement = null;
|
||||
ResultSet rs = null;
|
||||
|
||||
try
|
||||
{
|
||||
con = context.getDBConnection();
|
||||
TableRow reg = DatabaseManager.row("MetadataFieldRegistry");
|
||||
|
||||
String qualifierClause = "";
|
||||
|
||||
if (qualifier == null)
|
||||
{
|
||||
qualifierClause = "and qualifier is null";
|
||||
}
|
||||
else
|
||||
{
|
||||
qualifierClause = "and qualifier = ?";
|
||||
}
|
||||
|
||||
String query = "SELECT COUNT(*) FROM " + reg.getTable()
|
||||
+ " WHERE metadata_schema_id= ? "
|
||||
+ " and metadata_field_id != ? "
|
||||
+ " and element= ? " + qualifierClause;
|
||||
|
||||
statement = con.prepareStatement(query);
|
||||
statement.setInt(1,schemaID);
|
||||
statement.setInt(2,fieldID);
|
||||
statement.setString(3,element);
|
||||
|
||||
if (qualifier != null)
|
||||
{
|
||||
statement.setString(4,qualifier);
|
||||
}
|
||||
|
||||
rs = statement.executeQuery();
|
||||
|
||||
if (rs.next())
|
||||
{
|
||||
count = rs.getInt(1);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (rs != null)
|
||||
{
|
||||
try { rs.close(); } catch (SQLException sqle) { }
|
||||
}
|
||||
|
||||
if (statement != null)
|
||||
{
|
||||
try { statement.close(); } catch (SQLException sqle) { }
|
||||
}
|
||||
}
|
||||
|
||||
return (count == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the HTML FORM key for the given field.
|
||||
*
|
||||
* @param schema
|
||||
* @param element
|
||||
* @param qualifier
|
||||
* @return HTML FORM key
|
||||
*/
|
||||
public static String formKey(String schema, String element, String qualifier)
|
||||
{
|
||||
if (qualifier == null)
|
||||
{
|
||||
return schema + "_" + element;
|
||||
}
|
||||
else
|
||||
{
|
||||
return schema + "_" + element + "_" + qualifier;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the field corresponding to the given numeric ID. The ID is
|
||||
* a database key internal to DSpace.
|
||||
*
|
||||
* @param context
|
||||
* context, in case we need to read it in from DB
|
||||
* @param id
|
||||
* the metadata field ID
|
||||
* @return the metadata field object
|
||||
* @throws SQLException
|
||||
*/
|
||||
public static MetadataField find(Context context, int id)
|
||||
throws SQLException
|
||||
{
|
||||
if (!isCacheInitialized())
|
||||
{
|
||||
initCache(context);
|
||||
}
|
||||
|
||||
// 'sanity check' first.
|
||||
Integer iid = Integer.valueOf(id);
|
||||
if (!id2field.containsKey(iid))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return id2field.get(iid);
|
||||
}
|
||||
|
||||
// invalidate the cache e.g. after something modifies DB state.
|
||||
private static void decache()
|
||||
{
|
||||
id2field = null;
|
||||
}
|
||||
|
||||
private static boolean isCacheInitialized()
|
||||
{
|
||||
return id2field != null;
|
||||
}
|
||||
|
||||
// load caches if necessary
|
||||
private static synchronized void initCache(Context context) throws SQLException
|
||||
{
|
||||
if (!isCacheInitialized())
|
||||
{
|
||||
Map<Integer, MetadataField> new_id2field = new HashMap<Integer, MetadataField>();
|
||||
Map<String, MetadataField> new_metadatafieldcache = new HashMap<String, MetadataField>();
|
||||
log.info("Loading MetadataField elements into cache.");
|
||||
|
||||
// Grab rows from DB
|
||||
TableRowIterator tri = DatabaseManager.queryTable(context,"MetadataFieldRegistry",
|
||||
"SELECT * from MetadataFieldRegistry");
|
||||
|
||||
try
|
||||
{
|
||||
while (tri.hasNext())
|
||||
{
|
||||
TableRow row = tri.next();
|
||||
int fieldID = row.getIntColumn("metadata_field_id");
|
||||
MetadataField metadataField = new MetadataField(row);
|
||||
new_id2field.put(Integer.valueOf(fieldID), metadataField);
|
||||
new_metadatafieldcache.put(metadataField.getSchemaID()+"."+metadataField.getElement()+"."+metadataField.getQualifier(), metadataField);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
// close the TableRowIterator to free up resources
|
||||
if (tri != null)
|
||||
{
|
||||
tri.close();
|
||||
}
|
||||
}
|
||||
|
||||
id2field = new_id2field;
|
||||
metadatafieldcache = new_metadatafieldcache;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return <code>true</code> if <code>other</code> is the same MetadataField
|
||||
@@ -650,16 +158,17 @@ public class MetadataField
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass())
|
||||
Class<?> objClass = HibernateProxyHelper.getClassWithoutInitializingProxy(obj);
|
||||
if (getClass() != objClass)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final MetadataField other = (MetadataField) obj;
|
||||
if (this.fieldID != other.fieldID)
|
||||
if (this.getFieldID() != other.getFieldID())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (this.schemaID != other.schemaID)
|
||||
if (!getMetadataSchema().equals(other.getMetadataSchema()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -670,8 +179,24 @@ public class MetadataField
|
||||
public int hashCode()
|
||||
{
|
||||
int hash = 7;
|
||||
hash = 47 * hash + this.fieldID;
|
||||
hash = 47 * hash + this.schemaID;
|
||||
hash = 47 * hash + getFieldID();
|
||||
hash = 47 * hash + getMetadataSchema().getSchemaID();
|
||||
return hash;
|
||||
}
|
||||
|
||||
public String toString(char separator) {
|
||||
if (qualifier == null)
|
||||
{
|
||||
return getMetadataSchema().getName() + separator + element;
|
||||
}
|
||||
else
|
||||
{
|
||||
return getMetadataSchema().getName() + separator + element + separator + qualifier;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString('_');
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user