|| datastreamId.equals("FEDORA-AUDITTRAIL")) {
throw new GeneralException("Modification of the system-controlled AUDIT"
+ " datastream is not permitted.");
}
DOWriter w = null;
try {
logger.debug("Entered modifyDatastreamByReference");
m_authz
.enforceModifyDatastreamByReference(context,
pid,
datastreamId,
altIDs,
mimeType,
formatURI,
dsLocation,
checksumType,
checksum);
checkDatastreamLabel(dsLabel);
w = m_manager.getWriter(Server.USE_DEFINITIVE_STORE, context, pid);
org.fcrepo.server.storage.types.Datastream orig =
w.GetDatastream(datastreamId, null);
if (orig == null) {
throw new DatastreamNotFoundException("Object " + pid + " has no datastream "
+ datastreamId + " to modify");
}
// if provided, check request lastModifiedDate against the datastream,
// rejecting the request if the datastream's mod date is more recent.
if (lastModifiedDate != null) {
if (lastModifiedDate.before(orig.DSCreateDT)) {
String dsDate = DateUtility.convertDateToXSDString(w.getLastModDate());
String reqDate = DateUtility.convertDateToXSDString(lastModifiedDate);
String msg = String.format("%s/%s lastModifiedDate (%s) " +
"is more recent than the " +
"request (%s)", pid,
datastreamId, dsDate, reqDate);
throw new DatastreamLockedException(msg);
}
}
Date nowUTC; // variable for ds modified date
// some forbidden scenarios...
if (orig.DSControlGrp.equals("X")) {
throw new GeneralException("Inline XML datastreams must be modified by value, not by reference.");
}
if (orig.DSState.equals("D")) {
throw new GeneralException("Changing attributes on deleted datastreams is forbidden.");
}
// A NULL INPUT PARM MEANS NO CHANGE TO DS ATTRIBUTE...
// if input parms are null, the ds attribute should not be changed,
// so set the parm values to the existing values in the datastream.
if (dsLabel == null) {
dsLabel = orig.DSLabel;
}
if (mimeType == null) {
mimeType = orig.DSMIME;
}
if (formatURI == null) {
formatURI = orig.DSFormatURI;
}
if (altIDs == null) {
altIDs = orig.DatastreamAltIDs;
}
if (checksumType == null) {
checksumType = orig.DSChecksumType;
} else {
checksumType = Datastream.validateChecksumType(checksumType);
}
// In cases where an empty attribute value is not allowed, then
// NULL or EMPTY PARM means no change to ds attribute...
if (dsLocation == null || dsLocation.equals("")) {
if (orig.DSControlGrp.equals("M")) {
// if managed content location is unspecified,
// cause a copy of the prior content to be made at
// commit-time
dsLocation = DatastreamManagedContent.COPY_SCHEME + orig.DSLocation;
} else {
dsLocation = orig.DSLocation;
}
} else {
ValidationUtility.validateURL(dsLocation, orig.DSControlGrp);
}
// if "force" is false and the mime type changed, validate the
// original datastream with respect to any disseminators it is
// involved in, and keep a record of that information for later
// (so we can determine whether the mime type change would cause
// data contract invalidation)
// Map oldValidationReports = null;
// if ( !mimeType.equals(orig.DSMIME) && !force) {
// oldValidationReports = getAllBindingMapValidationReports(
// context, w, datastreamId);
// }
// instantiate the right class of datastream
// (inline xml "X" datastreams have already been rejected)
Datastream newds;
if (orig.DSControlGrp.equals("M")) {
newds = new DatastreamManagedContent();
} else {
newds = new DatastreamReferencedContent();
}
// update ds attributes that are common to all versions...
// first, those that cannot be changed by client...
newds.DatastreamID = orig.DatastreamID;
newds.DSControlGrp = orig.DSControlGrp;
newds.DSInfoType = orig.DSInfoType;
// next, those that can be changed by client...
newds.DSState = orig.DSState;
newds.DSVersionable = orig.DSVersionable;
// update ds version-level attributes, and
// make sure ds gets a new version id
newds.DSVersionID = w.newDatastreamID(datastreamId);
newds.DSLabel = dsLabel;
newds.DSMIME = mimeType;
newds.DSFormatURI = formatURI;
newds.DatastreamAltIDs = altIDs;
nowUTC = Server.getCurrentDate(context);
newds.DSCreateDT = nowUTC;
// newds.DSSize will be computed later
newds.DSLocation = dsLocation;
newds.DSLocationType = Datastream.DS_LOCATION_TYPE_URL;
newds.DSChecksumType = checksumType;
// validate reserved datastreams (type M and X) unless unchanged:
if (!newds.DSLocation.startsWith(DatastreamManagedContent.COPY_SCHEME) &&
!newds.DSLocation.equals(orig.DSLocation)) {
ValidationUtility.validateReservedDatastream(PID.getInstance(pid),
datastreamId,
newds);
}
// next, add the datastream via the object writer
w.addDatastream(newds, orig.DSVersionable);
// if a checksum is passed in verify that the checksum computed for
// the datastream
// matches the one that is passed in.
if (checksum != null) {
if (checksumType == null) {
newds.DSChecksumType = orig.DSChecksumType;
}
String check = newds.getChecksum();
if (!checksum.equals(check)) {
throw new ValidationException("Checksum Mismatch: " + check);
}
}
// Update audit trail
addAuditRecord(context,
w,
"modifyDatastreamByReference",
newds.DatastreamID,
logMessage,
nowUTC);
// if all went ok, check if we need to validate, then commit.
// if (oldValidationReports != null) { // mime changed and
// force=false
// rejectMimeChangeIfCausedInvalidation(
// oldValidationReports,
// getAllBindingMapValidationReports(context,
// w,
// datastreamId));
// }
w.commit(logMessage);
return nowUTC;
} finally {
// Logger completion
if (logger.isInfoEnabled()) {