mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-07 18:14:26 +00:00
1387 lines
52 KiB
Java
1387 lines
52 KiB
Java
/**
|
|
* 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.sql.SQLException;
|
|
import java.util.*;
|
|
|
|
import org.apache.commons.lang.ArrayUtils;
|
|
import org.apache.log4j.Logger;
|
|
|
|
import org.apache.commons.lang.StringUtils;
|
|
import org.apache.log4j.Logger;
|
|
import org.dspace.authorize.AuthorizeException;
|
|
import org.dspace.content.authority.ChoiceAuthorityManager;
|
|
import org.dspace.content.authority.Choices;
|
|
import org.dspace.content.authority.MetadataAuthorityManager;
|
|
import org.dspace.core.Constants;
|
|
import org.dspace.core.Context;
|
|
import org.dspace.core.LogManager;
|
|
import org.dspace.eperson.EPerson;
|
|
import org.dspace.eperson.Group;
|
|
import org.dspace.event.Event;
|
|
import org.dspace.storage.rdbms.DatabaseManager;
|
|
import org.dspace.storage.rdbms.TableRow;
|
|
import org.dspace.storage.rdbms.TableRowIterator;
|
|
import org.dspace.handle.HandleManager;
|
|
import org.dspace.identifier.IdentifierService;
|
|
import org.dspace.utils.DSpace;
|
|
|
|
/**
|
|
* Abstract base class for DSpace objects
|
|
*/
|
|
public abstract class DSpaceObject
|
|
{
|
|
/** Our context */
|
|
protected Context ourContext;
|
|
|
|
/** log4j category */
|
|
private static final Logger log = Logger.getLogger(DSpaceObject.class);
|
|
|
|
/**
|
|
* True if anything else was changed since last update()
|
|
* (to drive event mechanism)
|
|
*/
|
|
protected boolean modifiedMetadata;
|
|
|
|
|
|
// accumulate information to add to "detail" element of content Event,
|
|
// e.g. to document metadata fields touched, etc.
|
|
private StringBuffer eventDetails = null;
|
|
|
|
private String[] identifiers = null;
|
|
|
|
/** The Dublin Core metadata - inner class for lazy loading */
|
|
protected MetadataCache metadataCache = new MetadataCache();
|
|
|
|
|
|
/**
|
|
* Construct a DSpaceOBject with the given table row
|
|
*
|
|
* @throws SQLException
|
|
*/
|
|
protected DSpaceObject()
|
|
{
|
|
modifiedMetadata = false;
|
|
}
|
|
|
|
protected DSpaceObject(Context context)
|
|
{
|
|
ourContext = context;
|
|
modifiedMetadata = false;
|
|
}
|
|
|
|
|
|
public void updateMetadata() throws SQLException, AuthorizeException {
|
|
// Map counting number of values for each element/qualifier.
|
|
// Keys are Strings: "element" or "element.qualifier"
|
|
// Values are Integers indicating number of values written for a
|
|
// element/qualifier
|
|
Map<String,Integer> elementCount = new HashMap<String,Integer>();
|
|
|
|
modifiedMetadata = false;
|
|
|
|
// Arrays to store the working information required
|
|
int[] placeNum = new int[getMetadata().size()];
|
|
boolean[] storedDC = new boolean[getMetadata().size()];
|
|
MetadataField[] dcFields = new MetadataField[getMetadata().size()];
|
|
|
|
// Work out the place numbers for the in memory DC
|
|
for (int dcIdx = 0; dcIdx < getMetadata().size(); dcIdx++)
|
|
{
|
|
DCValue dcv = getMetadata().get(dcIdx);
|
|
|
|
// Work out the place number for ordering
|
|
int current = 0;
|
|
|
|
// Key into map is "element" or "element.qualifier"
|
|
String key = dcv.element + ((dcv.qualifier == null) ? "" : ("." + dcv.qualifier));
|
|
|
|
Integer currentInteger = elementCount.get(key);
|
|
if (currentInteger != null)
|
|
{
|
|
current = currentInteger.intValue();
|
|
}
|
|
|
|
current++;
|
|
elementCount.put(key, Integer.valueOf(current));
|
|
|
|
// Store the calculated place number, reset the stored flag, and cache the metadatafield
|
|
placeNum[dcIdx] = current;
|
|
storedDC[dcIdx] = false;
|
|
dcFields[dcIdx] = getMetadataField(dcv);
|
|
if (dcFields[dcIdx] == null)
|
|
{
|
|
// Bad DC field, log and throw exception
|
|
log.warn("Invalid metadata field: [" + dcv.getField() + "] : [" + dcv.value + "]");
|
|
throw new SQLException("Invalid metadata field: [" + dcv.getField() + "]");
|
|
}
|
|
}
|
|
|
|
// Now the precalculations are done, iterate through the existing metadata
|
|
// looking for matches
|
|
TableRowIterator tri = retrieveMetadata();
|
|
if (tri != null)
|
|
{
|
|
try
|
|
{
|
|
while (tri.hasNext())
|
|
{
|
|
TableRow tr = tri.next();
|
|
// Assume that we will remove this row, unless we get a match
|
|
boolean removeRow = true;
|
|
|
|
// Go through the in-memory metadata, unless we've already decided to keep this row
|
|
for (int dcIdx = 0; dcIdx < getMetadata().size() && removeRow; dcIdx++)
|
|
{
|
|
// Only process if this metadata has not already been matched to something in the DB
|
|
if (!storedDC[dcIdx])
|
|
{
|
|
boolean matched = true;
|
|
DCValue dcv = getMetadata().get(dcIdx);
|
|
|
|
// Check the metadata field is the same
|
|
if (matched && dcFields[dcIdx].getFieldID() != tr.getIntColumn("metadata_field_id"))
|
|
{
|
|
matched = false;
|
|
}
|
|
|
|
// Check the place is the same
|
|
if (matched && placeNum[dcIdx] != tr.getIntColumn("place"))
|
|
{
|
|
matched = false;
|
|
}
|
|
|
|
// Check the text is the same
|
|
if (matched)
|
|
{
|
|
String text = tr.getStringColumn("text_value");
|
|
if (dcv.value == null && text == null)
|
|
{
|
|
matched = true;
|
|
}
|
|
else if (dcv.value != null && dcv.value.equals(text))
|
|
{
|
|
matched = true;
|
|
}
|
|
else
|
|
{
|
|
matched = false;
|
|
}
|
|
}
|
|
|
|
// Check the language is the same
|
|
if (matched)
|
|
{
|
|
String lang = tr.getStringColumn("text_lang");
|
|
if (dcv.language == null && lang == null)
|
|
{
|
|
matched = true;
|
|
}
|
|
else if (dcv.language != null && dcv.language.equals(lang))
|
|
{
|
|
matched = true;
|
|
}
|
|
else
|
|
{
|
|
matched = false;
|
|
}
|
|
}
|
|
|
|
// check that authority and confidence match
|
|
if (matched)
|
|
{
|
|
String auth = tr.getStringColumn("authority");
|
|
int conf = tr.getIntColumn("confidence");
|
|
if (!((dcv.authority == null && auth == null) ||
|
|
(dcv.authority != null && auth != null && dcv.authority.equals(auth))
|
|
&& dcv.confidence == conf))
|
|
{
|
|
matched = false;
|
|
}
|
|
}
|
|
|
|
// If the db record is identical to the in memory values
|
|
if (matched)
|
|
{
|
|
// Flag that the metadata is already in the DB
|
|
storedDC[dcIdx] = true;
|
|
|
|
// Flag that we are not going to remove the row
|
|
removeRow = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// If after processing all the metadata values, we didn't find a match
|
|
// delete this row from the DB
|
|
if (removeRow)
|
|
{
|
|
DatabaseManager.delete(ourContext, tr);
|
|
modifiedMetadata = true;
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
tri.close();
|
|
}
|
|
|
|
|
|
}
|
|
|
|
// Add missing in-memory DC
|
|
for (int dcIdx = 0; dcIdx < getMetadata().size(); dcIdx++)
|
|
{
|
|
// Only write values that are not already in the db
|
|
if (!storedDC[dcIdx])
|
|
{
|
|
DCValue dcv = getMetadata().get(dcIdx);
|
|
|
|
// Write DCValue
|
|
MetadataValue metadata = new MetadataValue();
|
|
metadata.setResourceId(getID());
|
|
metadata.setResourceTypeId(getType());
|
|
metadata.setFieldId(dcFields[dcIdx].getFieldID());
|
|
metadata.setValue(dcv.value);
|
|
metadata.setLanguage(dcv.language);
|
|
metadata.setPlace(placeNum[dcIdx]);
|
|
metadata.setAuthority(dcv.authority);
|
|
metadata.setConfidence(dcv.confidence);
|
|
metadata.create(ourContext);
|
|
modifiedMetadata = true;
|
|
}
|
|
}
|
|
|
|
if(modifiedMetadata) {
|
|
ourContext.addEvent(new Event(Event.MODIFY_METADATA, getType(), getID(), getDetails(), getIdentifiers(ourContext)));
|
|
modifiedMetadata = false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Reset the cache of event details.
|
|
*/
|
|
protected 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.
|
|
*/
|
|
protected 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();
|
|
|
|
/**
|
|
* Provide the text name of the type of this DSpaceObject. It is most likely all uppercase.
|
|
* @return Object type as text
|
|
*/
|
|
public String getTypeText()
|
|
{
|
|
return Constants.typeText[this.getType()];
|
|
}
|
|
|
|
/**
|
|
* Get the internal ID (database primary key) of this object
|
|
*
|
|
* @return internal ID of object
|
|
*/
|
|
public abstract int getID();
|
|
|
|
/**
|
|
* Get the Handle of the object. This may return <code>null</code>
|
|
*
|
|
* @return Handle of the object, or <code>null</code> if it doesn't have
|
|
* one
|
|
*/
|
|
public abstract String getHandle();
|
|
|
|
/**
|
|
* Get a proper name for the object. This may return <code>null</code>.
|
|
* Name should be suitable for display in a user interface.
|
|
*
|
|
* @return Name for the object, or <code>null</code> if it doesn't have
|
|
* one
|
|
*/
|
|
public abstract String getName();
|
|
|
|
/**
|
|
* Tries to lookup all Identifiers of this DSpaceObject.
|
|
* @return An array containing all found identifiers or an array with a length of 0.
|
|
*/
|
|
public String[] getIdentifiers(Context context)
|
|
{
|
|
if (identifiers == null)
|
|
{
|
|
log.debug("This DSO's identifiers cache is empty, looking for identifiers...");
|
|
identifiers = new String[0];
|
|
|
|
IdentifierService identifierService =
|
|
new DSpace().getSingletonService(IdentifierService.class);
|
|
|
|
if (identifierService != null)
|
|
{
|
|
identifiers = identifierService.lookup(context, this);
|
|
} else {
|
|
log.warn("No IdentifierService found, will return an array containing "
|
|
+ "the Handle only.");
|
|
if (getHandle() != null)
|
|
{
|
|
identifiers = new String[] { HandleManager.getCanonicalForm(getHandle()) };
|
|
}
|
|
}
|
|
}
|
|
|
|
// it the DSO has no identifiers at all including handle, we should return an empty array.
|
|
// G.e. items during submission (workspace items) have no handle and no other identifier.
|
|
if (identifiers == null)
|
|
{
|
|
identifiers = new String[] {};
|
|
}
|
|
|
|
if (log.isDebugEnabled())
|
|
{
|
|
StringBuilder dbgMsg = new StringBuilder();
|
|
for (String id : identifiers)
|
|
{
|
|
if (dbgMsg.capacity() == 0)
|
|
{
|
|
dbgMsg.append("This DSO's Identifiers are: ");
|
|
} else {
|
|
dbgMsg.append(", ");
|
|
}
|
|
dbgMsg.append(id);
|
|
}
|
|
dbgMsg.append(".");
|
|
log.debug(dbgMsg.toString());
|
|
}
|
|
|
|
return identifiers;
|
|
}
|
|
|
|
public void resetIdentifiersCache()
|
|
{
|
|
identifiers = null;
|
|
}
|
|
|
|
/**
|
|
* Generic find for when the precise type of a DSO is not known, just the
|
|
* a pair of type number and database ID.
|
|
*
|
|
* @param context - the context
|
|
* @param type - type number
|
|
* @param id - id within table of type'd objects
|
|
* @return the object found, or null if it does not exist.
|
|
* @throws SQLException only upon failure accessing the database.
|
|
*/
|
|
public static DSpaceObject find(Context context, int type, int id)
|
|
throws SQLException
|
|
{
|
|
switch (type)
|
|
{
|
|
case Constants.BITSTREAM : return Bitstream.find(context, id);
|
|
case Constants.BUNDLE : return Bundle.find(context, id);
|
|
case Constants.ITEM : return Item.find(context, id);
|
|
case Constants.COLLECTION: return Collection.find(context, id);
|
|
case Constants.COMMUNITY : return Community.find(context, id);
|
|
case Constants.GROUP : return Group.find(context, id);
|
|
case Constants.EPERSON : return EPerson.find(context, id);
|
|
case Constants.SITE : return Site.find(context, id);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Return the dspace object where an ADMIN action right is sufficient to
|
|
* grant the initial authorize check.
|
|
* <p>
|
|
* Default behaviour is ADMIN right on the object grant right on all other
|
|
* action on the object itself. Subclass should override this method as
|
|
* needed.
|
|
*
|
|
* @param action
|
|
* ID of action being attempted, from
|
|
* <code>org.dspace.core.Constants</code>. The ADMIN action is
|
|
* not a valid parameter for this method, an
|
|
* IllegalArgumentException should be thrown
|
|
* @return the dspace object, if any, where an ADMIN action is sufficient to
|
|
* grant the original action
|
|
* @throws SQLException
|
|
* @throws IllegalArgumentException
|
|
* if the ADMIN action is supplied as parameter of the method
|
|
* call
|
|
*/
|
|
public DSpaceObject getAdminObject(int action) throws SQLException
|
|
{
|
|
if (action == Constants.ADMIN)
|
|
{
|
|
throw new IllegalArgumentException("Illegal call to the DSpaceObject.getAdminObject method");
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Return the dspace object that "own" the current object in the hierarchy.
|
|
* Note that this method has a meaning slightly different from the
|
|
* getAdminObject because it is independent of the action but it is in a way
|
|
* related to it. It defines the "first" dspace object <b>OTHER</b> then the
|
|
* current one, where allowed ADMIN actions imply allowed ADMIN actions on
|
|
* the object self.
|
|
*
|
|
* @return the dspace object that "own" the current object in
|
|
* the hierarchy
|
|
* @throws SQLException
|
|
*/
|
|
public DSpaceObject getParentObject() throws SQLException
|
|
{
|
|
return null;
|
|
}
|
|
|
|
public abstract void update() throws SQLException, AuthorizeException;
|
|
|
|
public abstract void updateLastModified();
|
|
|
|
private TableRowIterator retrieveMetadata() throws SQLException
|
|
{
|
|
return DatabaseManager.queryTable(ourContext, "MetadataValue",
|
|
"SELECT * FROM MetadataValue WHERE resource_id= ? and resource_type_id = ? ORDER BY metadata_field_id, place",
|
|
getID(),
|
|
getType());
|
|
}
|
|
|
|
/**
|
|
* Get Dublin Core metadata for the DSpace Object.
|
|
* Passing in a <code>null</code> value for <code>qualifier</code>
|
|
* or <code>lang</code> only matches Dublin Core fields where that
|
|
* qualifier or languages is actually <code>null</code>.
|
|
* Passing in <code>DSpaceObject.ANY</code>
|
|
* retrieves all metadata fields with any value for the qualifier or
|
|
* language, including <code>null</code>
|
|
* <P>
|
|
* Examples:
|
|
* <P>
|
|
* Return values of the unqualified "title" field, in any language.
|
|
* Qualified title fields (e.g. "title.uniform") are NOT returned:
|
|
* <P>
|
|
* <code>dspaceobject.getDC( "title", null, DSpaceObject.ANY );</code>
|
|
* <P>
|
|
* Return all US English values of the "title" element, with any qualifier
|
|
* (including unqualified):
|
|
* <P>
|
|
* <code>dspaceobject.getDC( "title", DSpaceObject.ANY, "en_US" );</code>
|
|
* <P>
|
|
* The ordering of values of a particular element/qualifier/language
|
|
* combination is significant. When retrieving with wildcards, values of a
|
|
* particular element/qualifier/language combinations will be adjacent, but
|
|
* the overall ordering of the combinations is indeterminate.
|
|
*
|
|
* @param element
|
|
* the Dublin Core element. <code>DSpaceObject.ANY</code> matches any
|
|
* element. <code>null</code> doesn't really make sense as all
|
|
* DC must have an element.
|
|
* @param qualifier
|
|
* the qualifier. <code>null</code> means unqualified, and
|
|
* <code>DSpaceObject.ANY</code> means any qualifier (including
|
|
* unqualified.)
|
|
* @param lang
|
|
* the ISO639 language code, optionally followed by an underscore
|
|
* and the ISO3166 country code. <code>null</code> means only
|
|
* values with no language are returned, and
|
|
* <code>DSpaceObject.ANY</code> means values with any country code or
|
|
* no country code are returned.
|
|
* @return Dublin Core fields that match the parameters
|
|
*/
|
|
@Deprecated
|
|
public DCValue[] getDC(String element, String qualifier, String lang)
|
|
{
|
|
return getMetadata(MetadataSchema.DC_SCHEMA, element, qualifier, lang);
|
|
}
|
|
|
|
/**
|
|
* Get metadata for the DSpace Object in a chosen schema.
|
|
* See <code>MetadataSchema</code> for more information about schemas.
|
|
* Passing in a <code>null</code> value for <code>qualifier</code>
|
|
* or <code>lang</code> only matches metadata fields where that
|
|
* qualifier or languages is actually <code>null</code>.
|
|
* Passing in <code>DSpaceObject.ANY</code>
|
|
* retrieves all metadata fields with any value for the qualifier or
|
|
* language, including <code>null</code>
|
|
* <P>
|
|
* Examples:
|
|
* <P>
|
|
* Return values of the unqualified "title" field, in any language.
|
|
* Qualified title fields (e.g. "title.uniform") are NOT returned:
|
|
* <P>
|
|
* <code>dspaceobject.getMetadataByMetadataString("dc", "title", null, DSpaceObject.ANY );</code>
|
|
* <P>
|
|
* Return all US English values of the "title" element, with any qualifier
|
|
* (including unqualified):
|
|
* <P>
|
|
* <code>dspaceobject.getMetadataByMetadataString("dc, "title", DSpaceObject.ANY, "en_US" );</code>
|
|
* <P>
|
|
* The ordering of values of a particular element/qualifier/language
|
|
* combination is significant. When retrieving with wildcards, values of a
|
|
* particular element/qualifier/language combinations will be adjacent, but
|
|
* the overall ordering of the combinations is indeterminate.
|
|
*
|
|
* @param schema
|
|
* the schema for the metadata field. <em>Must</em> match
|
|
* the <code>name</code> of an existing metadata schema.
|
|
* @param element
|
|
* the element name. <code>DSpaceObject.ANY</code> matches any
|
|
* element. <code>null</code> doesn't really make sense as all
|
|
* metadata must have an element.
|
|
* @param qualifier
|
|
* the qualifier. <code>null</code> means unqualified, and
|
|
* <code>DSpaceObject.ANY</code> means any qualifier (including
|
|
* unqualified.)
|
|
* @param lang
|
|
* the ISO639 language code, optionally followed by an underscore
|
|
* and the ISO3166 country code. <code>null</code> means only
|
|
* values with no language are returned, and
|
|
* <code>DSpaceObject.ANY</code> means values with any country code or
|
|
* no country code are returned.
|
|
* @return metadata fields that match the parameters
|
|
*/
|
|
public DCValue[] getMetadata(String schema, String element, String qualifier,
|
|
String lang)
|
|
{
|
|
// Build up list of matching values
|
|
List<DCValue> values = new ArrayList<DCValue>();
|
|
for (DCValue dcv : getMetadata())
|
|
{
|
|
if (match(schema, element, qualifier, lang, dcv))
|
|
{
|
|
// We will return a copy of the object in case it is altered
|
|
DCValue copy = new DCValue();
|
|
copy.element = dcv.element;
|
|
copy.qualifier = dcv.qualifier;
|
|
copy.value = dcv.value;
|
|
copy.language = dcv.language;
|
|
copy.schema = dcv.schema;
|
|
copy.authority = dcv.authority;
|
|
copy.confidence = dcv.confidence;
|
|
values.add(copy);
|
|
}
|
|
}
|
|
|
|
// Create an array of matching values
|
|
DCValue[] valueArray = new DCValue[values.size()];
|
|
valueArray = (DCValue[]) values.toArray(valueArray);
|
|
|
|
return valueArray;
|
|
}
|
|
|
|
/**
|
|
* Retrieve metadata field values from a given metadata string
|
|
* of the form <schema prefix>.<element>[.<qualifier>|.*]
|
|
*
|
|
* @param mdString
|
|
* The metadata string of the form
|
|
* <schema prefix>.<element>[.<qualifier>|.*]
|
|
*/
|
|
public DCValue[] getMetadataByMetadataString(String mdString)
|
|
{
|
|
StringTokenizer dcf = new StringTokenizer(mdString, ".");
|
|
|
|
String[] tokens = { "", "", "" };
|
|
int i = 0;
|
|
while(dcf.hasMoreTokens())
|
|
{
|
|
tokens[i] = dcf.nextToken().trim();
|
|
i++;
|
|
}
|
|
String schema = tokens[0];
|
|
String element = tokens[1];
|
|
String qualifier = tokens[2];
|
|
|
|
DCValue[] values;
|
|
if ("*".equals(qualifier))
|
|
{
|
|
values = getMetadata(schema, element, Item.ANY, Item.ANY);
|
|
}
|
|
else if ("".equals(qualifier))
|
|
{
|
|
values = getMetadata(schema, element, null, Item.ANY);
|
|
}
|
|
else
|
|
{
|
|
values = getMetadata(schema, element, qualifier, Item.ANY);
|
|
}
|
|
|
|
return values;
|
|
}
|
|
|
|
/**
|
|
* Retrieve first metadata field value
|
|
*/
|
|
protected String getMetadataFirstValue(String schema, String element, String qualifier, String language){
|
|
DCValue[] dcvalues = getMetadata(schema, element, qualifier, Item.ANY);
|
|
if(dcvalues.length>0){
|
|
return dcvalues[0].value;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Set first metadata field value
|
|
*/
|
|
protected void setMetadataSingleValue(String schema, String element, String qualifier, String language, String value) {
|
|
if(value != null)
|
|
{
|
|
clearMetadata(schema, element, qualifier, language);
|
|
addMetadata(schema, element, qualifier, language, value);
|
|
modifiedMetadata = true;
|
|
}
|
|
}
|
|
|
|
protected List<DCValue> getMetadata()
|
|
{
|
|
try
|
|
{
|
|
return metadataCache.get(ourContext, getID(), getType(), log);
|
|
}
|
|
catch (SQLException e)
|
|
{
|
|
log.error("Loading item - cannot load metadata");
|
|
}
|
|
|
|
return new ArrayList<DCValue>();
|
|
}
|
|
|
|
/**
|
|
* Get the value of a metadata field
|
|
*
|
|
* @param value
|
|
* the name of the metadata field to get
|
|
*
|
|
* @return the value of the metadata field (or null if the column is an SQL NULL)
|
|
*
|
|
* @exception IllegalArgumentException
|
|
* if the requested metadata field doesn't exist
|
|
*/
|
|
public String getMetadata(String value){
|
|
DCValue[] dcvalues = getMetadataByMetadataString(value);
|
|
|
|
if(dcvalues.length>0) {
|
|
return dcvalues[0].value;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public List<DCValue> getMetadata(String mdString, String authority) {
|
|
String[] elements = getElements(mdString);
|
|
return getMetadata(elements[0], elements[1], elements[2], elements[3], authority);
|
|
}
|
|
|
|
public List<DCValue> getMetadata(String schema, String element, String qualifier, String lang, String authority) {
|
|
DCValue[] metadata = getMetadata(schema, element, qualifier, lang);
|
|
List<DCValue> dcValues = Arrays.asList(metadata);
|
|
if (!authority.equals(Item.ANY)) {
|
|
Iterator<DCValue> iterator = dcValues.iterator();
|
|
while (iterator.hasNext()) {
|
|
DCValue dcValue = iterator.next();
|
|
if (!authority.equals(dcValue.authority)) {
|
|
iterator.remove();
|
|
}
|
|
}
|
|
}
|
|
return dcValues;
|
|
}
|
|
|
|
|
|
/**
|
|
* Splits "schema.element.qualifier.language" into an array.
|
|
* <p/>
|
|
* The returned array will always have length >= 4
|
|
* <p/>
|
|
* Values in the returned array can be empty or null.
|
|
*/
|
|
public static String[] getElements(String fieldName) {
|
|
String[] tokens = StringUtils.split(fieldName, ".");
|
|
|
|
int add = 4 - tokens.length;
|
|
if (add > 0) {
|
|
tokens = (String[]) ArrayUtils.addAll(tokens, new String[add]);
|
|
}
|
|
|
|
return tokens;
|
|
}
|
|
|
|
/**
|
|
* Splits "schema.element.qualifier.language" into an array.
|
|
* <p/>
|
|
* The returned array will always have length >= 4
|
|
* <p/>
|
|
* When @param fill is true, elements that would be empty or null are replaced by Item.ANY
|
|
*/
|
|
public static String[] getElementsFilled(String fieldName) {
|
|
String[] elements = getElements(fieldName);
|
|
for (int i = 0; i < elements.length; i++) {
|
|
if (StringUtils.isBlank(elements[i])) {
|
|
elements[i] = Item.ANY;
|
|
}
|
|
}
|
|
return elements;
|
|
}
|
|
|
|
public void replaceMetadataValue(DCValue oldValue, DCValue newValue)
|
|
{
|
|
// check both dcvalues are for the same field
|
|
if (oldValue.hasSameFieldAs(newValue)) {
|
|
|
|
String schema = oldValue.schema;
|
|
String element = oldValue.element;
|
|
String qualifier = oldValue.qualifier;
|
|
|
|
// Save all metadata for this field
|
|
DCValue[] dcvalues = getMetadata(schema, element, qualifier, Item.ANY);
|
|
clearMetadata(schema, element, qualifier, Item.ANY);
|
|
for (DCValue dcvalue : dcvalues) {
|
|
if (dcvalue.equals(oldValue)) {
|
|
addMetadata(schema, element, qualifier, newValue.language, newValue.value, newValue.authority, newValue.confidence);
|
|
} else {
|
|
addMetadata(schema, element, qualifier, dcvalue.language, dcvalue.value, dcvalue.authority, dcvalue.confidence);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Add Dublin Core metadata fields. These are appended to existing values.
|
|
* Use <code>clearDC</code> to remove values. The ordering of values
|
|
* passed in is maintained.
|
|
*
|
|
* @param element
|
|
* the Dublin Core element
|
|
* @param qualifier
|
|
* the Dublin Core qualifier, or <code>null</code> for
|
|
* unqualified
|
|
* @param lang
|
|
* the ISO639 language code, optionally followed by an underscore
|
|
* and the ISO3166 country code. <code>null</code> means the
|
|
* value has no language (for example, a date).
|
|
* @param values
|
|
* the values to add.
|
|
*/
|
|
@Deprecated
|
|
public void addDC(String element, String qualifier, String lang,
|
|
String[] values)
|
|
{
|
|
addMetadata(MetadataSchema.DC_SCHEMA, element, qualifier, lang, values);
|
|
}
|
|
|
|
/**
|
|
* Add a single Dublin Core metadata field. This is appended to existing
|
|
* values. Use <code>clearDC</code> to remove values.
|
|
*
|
|
* @param element
|
|
* the Dublin Core element
|
|
* @param qualifier
|
|
* the Dublin Core qualifier, or <code>null</code> for
|
|
* unqualified
|
|
* @param lang
|
|
* the ISO639 language code, optionally followed by an underscore
|
|
* and the ISO3166 country code. <code>null</code> means the
|
|
* value has no language (for example, a date).
|
|
* @param value
|
|
* the value to add.
|
|
*/
|
|
@Deprecated
|
|
public void addDC(String element, String qualifier, String lang,
|
|
String value)
|
|
{
|
|
addMetadata(MetadataSchema.DC_SCHEMA, element, qualifier, lang, value);
|
|
}
|
|
|
|
/**
|
|
* Add metadata fields. These are appended to existing values.
|
|
* Use <code>clearDC</code> to remove values. The ordering of values
|
|
* passed in is maintained.
|
|
* <p>
|
|
* If metadata authority control is available, try to get authority
|
|
* values. The authority confidence depends on whether authority is
|
|
* <em>required</em> or not.
|
|
* @param schema
|
|
* the schema for the metadata field. <em>Must</em> match
|
|
* the <code>name</code> of an existing metadata schema.
|
|
* @param element
|
|
* the metadata element name
|
|
* @param qualifier
|
|
* the metadata qualifier name, or <code>null</code> for
|
|
* unqualified
|
|
* @param lang
|
|
* the ISO639 language code, optionally followed by an underscore
|
|
* and the ISO3166 country code. <code>null</code> means the
|
|
* value has no language (for example, a date).
|
|
* @param values
|
|
* the values to add.
|
|
*/
|
|
public void addMetadata(String schema, String element, String qualifier, String lang,
|
|
String[] values)
|
|
{
|
|
MetadataAuthorityManager mam = MetadataAuthorityManager.getManager();
|
|
String fieldKey = MetadataAuthorityManager.makeFieldKey(schema, element, qualifier);
|
|
if (mam.isAuthorityControlled(fieldKey))
|
|
{
|
|
String authorities[] = new String[values.length];
|
|
int confidences[] = new int[values.length];
|
|
for (int i = 0; i < values.length; ++i)
|
|
{
|
|
getAuthoritiesAndConfidences(fieldKey, values, authorities, confidences, i);
|
|
}
|
|
addMetadata(schema, element, qualifier, lang, values, authorities, confidences);
|
|
}
|
|
else
|
|
{
|
|
addMetadata(schema, element, qualifier, lang, values, null, null);
|
|
}
|
|
}
|
|
|
|
protected void getAuthoritiesAndConfidences(String fieldKey, String[] values, String[] authorities, int[] confidences, int i) {
|
|
Choices c = ChoiceAuthorityManager.getManager().getBestMatch(fieldKey, values[i], -1, null);
|
|
authorities[i] = c.values.length > 0 ? c.values[0].authority : null;
|
|
confidences[i] = c.confidence;
|
|
}
|
|
|
|
/**
|
|
* Add metadata fields. These are appended to existing values.
|
|
* Use <code>clearDC</code> to remove values. The ordering of values
|
|
* passed in is maintained.
|
|
* @param schema
|
|
* the schema for the metadata field. <em>Must</em> match
|
|
* the <code>name</code> of an existing metadata schema.
|
|
* @param element
|
|
* the metadata element name
|
|
* @param qualifier
|
|
* the metadata qualifier name, or <code>null</code> for
|
|
* unqualified
|
|
* @param lang
|
|
* the ISO639 language code, optionally followed by an underscore
|
|
* and the ISO3166 country code. <code>null</code> means the
|
|
* value has no language (for example, a date).
|
|
* @param values
|
|
* the values to add.
|
|
* @param authorities
|
|
* the external authority key for this value (or null)
|
|
* @param confidences
|
|
* the authority confidence (default 0)
|
|
*/
|
|
public void addMetadata(String schema, String element, String qualifier, String lang,
|
|
String[] values, String authorities[], int confidences[])
|
|
{
|
|
List<DCValue> dublinCore = getMetadata();
|
|
MetadataAuthorityManager mam = MetadataAuthorityManager.getManager();
|
|
boolean authorityControlled = mam.isAuthorityControlled(schema, element, qualifier);
|
|
boolean authorityRequired = mam.isAuthorityRequired(schema, element, qualifier);
|
|
String fieldName = schema+"."+element+((qualifier==null)? "": "."+qualifier);
|
|
|
|
// We will not verify that they are valid entries in the registry
|
|
// until update() is called.
|
|
for (int i = 0; i < values.length; i++)
|
|
{
|
|
DCValue dcv = new DCValue();
|
|
dcv.schema = schema;
|
|
dcv.element = element;
|
|
dcv.qualifier = qualifier;
|
|
dcv.language = (lang == null ? null : lang.trim());
|
|
|
|
// Logic to set Authority and Confidence:
|
|
// - normalize an empty string for authority to NULL.
|
|
// - if authority key is present, use given confidence or NOVALUE if not given
|
|
// - otherwise, preserve confidence if meaningful value was given since it may document a failed authority lookup
|
|
// - CF_UNSET signifies no authority nor meaningful confidence.
|
|
// - it's possible to have empty authority & CF_ACCEPTED if e.g. user deletes authority key
|
|
if (authorityControlled)
|
|
{
|
|
if (authorities != null && authorities[i] != null && authorities[i].length() > 0)
|
|
{
|
|
dcv.authority = authorities[i];
|
|
dcv.confidence = confidences == null ? Choices.CF_NOVALUE : confidences[i];
|
|
}
|
|
else
|
|
{
|
|
dcv.authority = null;
|
|
dcv.confidence = confidences == null ? Choices.CF_UNSET : confidences[i];
|
|
}
|
|
// authority sanity check: if authority is required, was it supplied?
|
|
// XXX FIXME? can't throw a "real" exception here without changing all the callers to expect it, so use a runtime exception
|
|
if (authorityRequired && (dcv.authority == null || dcv.authority.length() == 0))
|
|
{
|
|
throw new IllegalArgumentException("The metadata field \"" + fieldName + "\" requires an authority key but none was provided. Vaue=\"" + dcv.value + "\"");
|
|
}
|
|
}
|
|
if (values[i] != null)
|
|
{
|
|
// remove control unicode char
|
|
String temp = values[i].trim();
|
|
char[] dcvalue = temp.toCharArray();
|
|
for (int charPos = 0; charPos < dcvalue.length; charPos++)
|
|
{
|
|
if (Character.isISOControl(dcvalue[charPos]) &&
|
|
!String.valueOf(dcvalue[charPos]).equals("\u0009") &&
|
|
!String.valueOf(dcvalue[charPos]).equals("\n") &&
|
|
!String.valueOf(dcvalue[charPos]).equals("\r"))
|
|
{
|
|
dcvalue[charPos] = ' ';
|
|
}
|
|
}
|
|
dcv.value = String.valueOf(dcvalue);
|
|
}
|
|
else
|
|
{
|
|
dcv.value = null;
|
|
}
|
|
dublinCore.add(dcv);
|
|
addDetails(fieldName);
|
|
}
|
|
|
|
if (values.length > 0)
|
|
{
|
|
modifiedMetadata = true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add a single metadata field. This is appended to existing
|
|
* values. Use <code>clearDC</code> to remove values.
|
|
*
|
|
* @param schema
|
|
* the schema for the metadata field. <em>Must</em> match
|
|
* the <code>name</code> of an existing metadata schema.
|
|
* @param element
|
|
* the metadata element name
|
|
* @param qualifier
|
|
* the metadata qualifier, or <code>null</code> for
|
|
* unqualified
|
|
* @param lang
|
|
* the ISO639 language code, optionally followed by an underscore
|
|
* and the ISO3166 country code. <code>null</code> means the
|
|
* value has no language (for example, a date).
|
|
* @param value
|
|
* the value to add.
|
|
*/
|
|
public void addMetadata(String schema, String element, String qualifier,
|
|
String lang, String value)
|
|
{
|
|
String[] valArray = new String[1];
|
|
valArray[0] = value;
|
|
|
|
addMetadata(schema, element, qualifier, lang, valArray);
|
|
}
|
|
|
|
/**
|
|
* Add a single metadata field. This is appended to existing
|
|
* values. Use <code>clearDC</code> to remove values.
|
|
*
|
|
* @param schema
|
|
* the schema for the metadata field. <em>Must</em> match
|
|
* the <code>name</code> of an existing metadata schema.
|
|
* @param element
|
|
* the metadata element name
|
|
* @param qualifier
|
|
* the metadata qualifier, or <code>null</code> for
|
|
* unqualified
|
|
* @param lang
|
|
* the ISO639 language code, optionally followed by an underscore
|
|
* and the ISO3166 country code. <code>null</code> means the
|
|
* value has no language (for example, a date).
|
|
* @param value
|
|
* the value to add.
|
|
* @param authority
|
|
* the external authority key for this value (or null)
|
|
* @param confidence
|
|
* the authority confidence (default 0)
|
|
*/
|
|
public void addMetadata(String schema, String element, String qualifier,
|
|
String lang, String value, String authority, int confidence)
|
|
{
|
|
String[] valArray = new String[1];
|
|
String[] authArray = new String[1];
|
|
int[] confArray = new int[1];
|
|
valArray[0] = value;
|
|
authArray[0] = authority;
|
|
confArray[0] = confidence;
|
|
|
|
addMetadata(schema, element, qualifier, lang, valArray, authArray, confArray);
|
|
}
|
|
|
|
/**
|
|
* Clear Dublin Core metadata values. As with <code>getDC</code> above,
|
|
* passing in <code>null</code> only matches fields where the qualifier or
|
|
* language is actually <code>null</code>.<code>Item.ANY</code> will
|
|
* match any element, qualifier or language, including <code>null</code>.
|
|
* Thus, <code>idspaceobject.clearDC(DSpaceObject.ANY, DSpaceObject.ANY, DSpaceObject.ANY)</code> will
|
|
* remove all Dublin Core metadata associated with an DSpaceObject.
|
|
*
|
|
* @param element
|
|
* the Dublin Core element to remove, or <code>Item.ANY</code>
|
|
* @param qualifier
|
|
* the qualifier. <code>null</code> means unqualified, and
|
|
* <code>Item.ANY</code> means any qualifier (including
|
|
* unqualified.)
|
|
* @param lang
|
|
* the ISO639 language code, optionally followed by an underscore
|
|
* and the ISO3166 country code. <code>null</code> means only
|
|
* values with no language are removed, and <code>Item.ANY</code>
|
|
* means values with any country code or no country code are
|
|
* removed.
|
|
*/
|
|
@Deprecated
|
|
public void clearDC(String element, String qualifier, String lang)
|
|
{
|
|
clearMetadata(MetadataSchema.DC_SCHEMA, element, qualifier, lang);
|
|
}
|
|
|
|
/**
|
|
* Clear metadata values. As with <code>getDC</code> above,
|
|
* passing in <code>null</code> only matches fields where the qualifier or
|
|
* language is actually <code>null</code>.<code>Item.ANY</code> will
|
|
* match any element, qualifier or language, including <code>null</code>.
|
|
* Thus, <code>dspaceobject.clearDC(Item.ANY, Item.ANY, Item.ANY)</code> will
|
|
* remove all Dublin Core metadata associated with an DSpaceObject.
|
|
*
|
|
* @param schema
|
|
* the schema for the metadata field. <em>Must</em> match
|
|
* the <code>name</code> of an existing metadata schema.
|
|
* @param element
|
|
* the Dublin Core element to remove, or <code>Item.ANY</code>
|
|
* @param qualifier
|
|
* the qualifier. <code>null</code> means unqualified, and
|
|
* <code>Item.ANY</code> means any qualifier (including
|
|
* unqualified.)
|
|
* @param lang
|
|
* the ISO639 language code, optionally followed by an underscore
|
|
* and the ISO3166 country code. <code>null</code> means only
|
|
* values with no language are removed, and <code>Item.ANY</code>
|
|
* means values with any country code or no country code are
|
|
* removed.
|
|
*/
|
|
public void clearMetadata(String schema, String element, String qualifier,
|
|
String lang)
|
|
{
|
|
// We will build a list of values NOT matching the values to clear
|
|
List<DCValue> values = new ArrayList<DCValue>();
|
|
for (DCValue dcv : getMetadata())
|
|
{
|
|
if (!match(schema, element, qualifier, lang, dcv))
|
|
{
|
|
values.add(dcv);
|
|
}
|
|
}
|
|
|
|
// Now swap the old list of values for the new, unremoved values
|
|
setMetadata(values);
|
|
modifiedMetadata = true;
|
|
}
|
|
|
|
/**
|
|
* Utility method for pattern-matching metadata elements. This
|
|
* method will return <code>true</code> if the given schema,
|
|
* element, qualifier and language match the schema, element,
|
|
* qualifier and language of the <code>DCValue</code> object passed
|
|
* in. Any or all of the element, qualifier and language passed
|
|
* in can be the <code>Item.ANY</code> wildcard.
|
|
*
|
|
* @param schema
|
|
* the schema for the metadata field. <em>Must</em> match
|
|
* the <code>name</code> of an existing metadata schema.
|
|
* @param element
|
|
* the element to match, or <code>Item.ANY</code>
|
|
* @param qualifier
|
|
* the qualifier to match, or <code>Item.ANY</code>
|
|
* @param language
|
|
* the language to match, or <code>Item.ANY</code>
|
|
* @param dcv
|
|
* the Dublin Core value
|
|
* @return <code>true</code> if there is a match
|
|
*/
|
|
private boolean match(String schema, String element, String qualifier,
|
|
String language, DCValue dcv)
|
|
{
|
|
// We will attempt to disprove a match - if we can't we have a match
|
|
if (!element.equals(Item.ANY) && !element.equals(dcv.element))
|
|
{
|
|
// Elements do not match, no wildcard
|
|
return false;
|
|
}
|
|
|
|
if (qualifier == null)
|
|
{
|
|
// Value must be unqualified
|
|
if (dcv.qualifier != null)
|
|
{
|
|
// Value is qualified, so no match
|
|
return false;
|
|
}
|
|
}
|
|
else if (!qualifier.equals(Item.ANY))
|
|
{
|
|
// Not a wildcard, so qualifier must match exactly
|
|
if (!qualifier.equals(dcv.qualifier))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (language == null)
|
|
{
|
|
// Value must be null language to match
|
|
if (dcv.language != null)
|
|
{
|
|
// Value is qualified, so no match
|
|
return false;
|
|
}
|
|
}
|
|
else if (!language.equals(Item.ANY))
|
|
{
|
|
// Not a wildcard, so language must match exactly
|
|
if (!language.equals(dcv.language))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (!schema.equals(Item.ANY))
|
|
{
|
|
if (dcv.schema != null && !dcv.schema.equals(schema))
|
|
{
|
|
// The namespace doesn't match
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// If we get this far, we have a match
|
|
return true;
|
|
}
|
|
|
|
protected transient MetadataField[] allMetadataFields = null;
|
|
protected MetadataField getMetadataField(DCValue dcv) throws SQLException, AuthorizeException
|
|
{
|
|
if (allMetadataFields == null)
|
|
{
|
|
allMetadataFields = MetadataField.findAll(ourContext);
|
|
}
|
|
|
|
if (allMetadataFields != null)
|
|
{
|
|
int schemaID = getMetadataSchemaID(dcv);
|
|
for (MetadataField field : allMetadataFields)
|
|
{
|
|
if (field.getSchemaID() == schemaID &&
|
|
StringUtils.equals(field.getElement(), dcv.element) &&
|
|
StringUtils.equals(field.getQualifier(), dcv.qualifier))
|
|
{
|
|
return field;
|
|
}
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private int getMetadataSchemaID(DCValue dcv) throws SQLException
|
|
{
|
|
int schemaID;
|
|
MetadataSchema schema = MetadataSchema.find(ourContext,dcv.schema);
|
|
if (schema == null)
|
|
{
|
|
schemaID = MetadataSchema.DC_SCHEMA_ID;
|
|
}
|
|
else
|
|
{
|
|
schemaID = schema.getSchemaID();
|
|
}
|
|
return schemaID;
|
|
}
|
|
|
|
/**
|
|
* Utility method to remove all descriptive metadata associated with the DSpaceObject from
|
|
* the database (regardless of in-memory version)
|
|
*
|
|
* @throws SQLException
|
|
*/
|
|
protected void removeMetadataFromDatabase() throws SQLException
|
|
{
|
|
DatabaseManager.updateQuery(ourContext,
|
|
"DELETE FROM MetadataValue WHERE resource_id= ? and resource_type_id=?",
|
|
getID(),
|
|
getType());
|
|
}
|
|
|
|
private void setMetadata(List<DCValue> metadata)
|
|
{
|
|
metadataCache.set(metadata);
|
|
modifiedMetadata = true;
|
|
}
|
|
|
|
class MetadataCache
|
|
{
|
|
List<DCValue> metadata = null;
|
|
|
|
List<DCValue> get(Context c, int resourceId, int resourceTypeId, Logger log) throws SQLException
|
|
{
|
|
if (metadata == null)
|
|
{
|
|
metadata = new ArrayList<DCValue>();
|
|
|
|
// Get Dublin Core metadata
|
|
TableRowIterator tri = retrieveMetadata(resourceId, resourceTypeId);
|
|
|
|
if (tri != null)
|
|
{
|
|
try
|
|
{
|
|
while (tri.hasNext())
|
|
{
|
|
TableRow resultRow = tri.next();
|
|
|
|
// Get the associated metadata field and schema information
|
|
int fieldID = resultRow.getIntColumn("metadata_field_id");
|
|
MetadataField field = MetadataField.find(c, fieldID);
|
|
|
|
if (field == null)
|
|
{
|
|
log.error("Loading item - cannot find metadata field " + fieldID + " for resourceType=" + resourceTypeId + " and resourceId=" + resourceId);
|
|
}
|
|
else
|
|
{
|
|
MetadataSchema schema = MetadataSchema.find(c, field.getSchemaID());
|
|
if (schema == null)
|
|
{
|
|
log.error("Loading item - cannot find metadata schema " + field.getSchemaID() + ", field " + fieldID);
|
|
}
|
|
else
|
|
{
|
|
// Make a DCValue object
|
|
DCValue dcv = new DCValue();
|
|
dcv.element = field.getElement();
|
|
dcv.qualifier = field.getQualifier();
|
|
dcv.value = resultRow.getStringColumn("text_value");
|
|
dcv.language = resultRow.getStringColumn("text_lang");
|
|
//dcv.namespace = schema.getNamespace();
|
|
dcv.schema = schema.getName();
|
|
dcv.authority = resultRow.getStringColumn("authority");
|
|
dcv.confidence = resultRow.getIntColumn("confidence");
|
|
|
|
// Add it to the list
|
|
metadata.add(dcv);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
// close the TableRowIterator to free up resources
|
|
if (tri != null)
|
|
{
|
|
tri.close();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return metadata;
|
|
}
|
|
|
|
void set(List<DCValue> m)
|
|
{
|
|
metadata = m;
|
|
}
|
|
|
|
TableRowIterator retrieveMetadata(int resourceId, int resourceTypeId) throws SQLException
|
|
{
|
|
return DatabaseManager.queryTable(ourContext, "MetadataValue",
|
|
"SELECT * FROM MetadataValue WHERE resource_id= ? and resource_type_id = ? ORDER BY metadata_field_id, place",
|
|
resourceId,
|
|
resourceTypeId);
|
|
}
|
|
}
|
|
|
|
protected String[] getMDValueByField(String field){
|
|
StringTokenizer dcf = new StringTokenizer(field, ".");
|
|
|
|
String[] tokens = { "", "", "" };
|
|
int i = 0;
|
|
while(dcf.hasMoreTokens()){
|
|
tokens[i] = dcf.nextToken().trim();
|
|
i++;
|
|
}
|
|
|
|
if(i!=0){
|
|
return tokens;
|
|
}else{
|
|
return getMDValueByLegacyField(field);
|
|
}
|
|
}
|
|
|
|
protected String[] getMDValueByLegacyField(String field){
|
|
switch (field) {
|
|
case "introductory_text":
|
|
return new String[]{MetadataSchema.DC_SCHEMA, "description", null};
|
|
case "short_description":
|
|
return new String[]{MetadataSchema.DC_SCHEMA, "description", "abstract"};
|
|
case "side_bar_text":
|
|
return new String[]{MetadataSchema.DC_SCHEMA, "description", "tableofcontents"};
|
|
case "copyright_text":
|
|
return new String[]{MetadataSchema.DC_SCHEMA, "rights", null};
|
|
case "name":
|
|
return new String[]{MetadataSchema.DC_SCHEMA, "title", null};
|
|
case "provenance_description":
|
|
return new String[]{MetadataSchema.DC_SCHEMA,"provenance", null};
|
|
case "license":
|
|
return new String[]{MetadataSchema.DC_SCHEMA, "rights", "license"};
|
|
case "user_format_description":
|
|
return new String[]{MetadataSchema.DC_SCHEMA,"format",null};
|
|
case "source":
|
|
return new String[]{MetadataSchema.DC_SCHEMA,"source",null};
|
|
case "firstname":
|
|
return new String[]{"eperson","firstname",null};
|
|
case "lastname":
|
|
return new String[]{"eperson","lastname",null};
|
|
case "phone":
|
|
return new String[]{"eperson","phone",null};
|
|
case "language":
|
|
return new String[]{"eperson","language",null};
|
|
default:
|
|
return new String[]{null, null, null};
|
|
}
|
|
}
|
|
|
|
} |