checksumType,
checksum);
checkDatastreamLabel(dsLabel);
w = m_manager.getWriter(Server.USE_DEFINITIVE_STORE, context, pid);
Datastream orig =
w.GetDatastream(datastreamId, null);
if (orig == null) {
throw new DatastreamNotFoundException("Object " + pid + " has no datastream "
+ datastreamId + " to modify");
}
XMLDatastreamProcessor origxml = new XMLDatastreamProcessor(orig);
// 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);
}
}
// some forbidden scenarios...
if (orig.DSState.equals("D")) {
throw new GeneralException("Changing attributes on deleted datastreams is forbidden.");
}
if (!orig.DSControlGrp.equals("X") && !orig.DSControlGrp.equals("M")) {
throw new GeneralException("Only content of inline XML and managed content"
+ " datastreams may be modified by value.\n"
+ "Use modifyDatastreamByReference instead.");
}
// 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);
}
if (dsContent != null && "DC".equals(datastreamId)){
DCFields audited = new DCFields(dsContent);
try {
dsContent = new ByteArrayInputStream(audited.getAsXML(pid).getBytes("UTF-8"));
} catch (UnsupportedEncodingException uee) {
// safely ignore... we know UTF-8 works
}
}
// create new datastream (version) based on existing one
XMLDatastreamProcessor newdsxml = origxml.newVersion();
Datastream newds = newdsxml.getDatastream();
newdsxml.setDSMDClass(origxml.getDSMDClass());
if (dsContent == null) {
// If the dsContent input stream parm is null,
// that means "do not change the content".
// Accordingly, here we just make a copy of the old content.
newdsxml.setXMLContent(origxml.getXMLContent());
} else {
// set and validate the content
newdsxml.setXMLContent(getEmbeddableXML(dsContent));
ValidationUtility.validateReservedDatastream(PID.getInstance(pid),
orig.DatastreamID,
newds);
}
// 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.DatastreamAltIDs = altIDs;
newds.DSMIME = mimeType;
newds.DSFormatURI = formatURI;
Date nowUTC = Server.getCurrentDate(context);
newds.DSCreateDT = nowUTC;
newds.DSChecksumType = checksumType;
// 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) {
String check = newds.getChecksum();
if (!checksum.equals(check)) {
throw new ValidationException("Checksum Mismatch: " + check);
}
}