/**
* Copyright 2008 The University of North Carolina at Chapel Hill
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package edu.unc.lib.dl.cdr.services;
import static edu.unc.lib.dl.util.JMSMessageUtil.ServicesActions.APPLY_SERVICE;
import static edu.unc.lib.dl.util.JMSMessageUtil.ServicesActions.APPLY_SERVICE_STACK;
import java.util.regex.Pattern;
import edu.unc.lib.dl.cdr.services.exception.EnhancementException;
import edu.unc.lib.dl.cdr.services.model.EnhancementMessage;
import edu.unc.lib.dl.cdr.services.model.FedoraEventMessage;
import edu.unc.lib.dl.fedora.FedoraException;
import edu.unc.lib.dl.fedora.PID;
import edu.unc.lib.dl.util.ContentModelHelper;
import edu.unc.lib.dl.util.ContentModelHelper.Datastream;
import edu.unc.lib.dl.util.JMSMessageUtil;
import edu.unc.lib.dl.util.JMSMessageUtil.FedoraActions;
public abstract class AbstractDatastreamEnhancementService extends AbstractIrodsObjectEnhancementService {
protected String derivativeDatastream;
protected Pattern mimetypePattern;
private final static String OCTET_STREAM_MIMETYPE = "application/octet-stream";
@Override
public boolean prefilterMessage(EnhancementMessage message) throws EnhancementException {
String action = message.getQualifiedAction();
if (JMSMessageUtil.ServicesActions.APPLY_SERVICE_STACK.equals(action))
return true;
if (JMSMessageUtil.ServicesActions.APPLY_SERVICE.equals(action))
return this.getClass().getName().equals(message.getServiceName());
// If its not a Fedora message at this point, then its not going to match anything else
if (!(message instanceof FedoraEventMessage))
return false;
if (JMSMessageUtil.FedoraActions.INGEST.equals(action))
return true;
if (!JMSMessageUtil.FedoraActions.MODIFY_DATASTREAM_BY_REFERENCE.equals(action)
&& !JMSMessageUtil.FedoraActions.ADD_DATASTREAM.equals(action)
&& !JMSMessageUtil.FedoraActions.MODIFY_DATASTREAM_BY_VALUE.equals(action))
return false;
String datastream = ((FedoraEventMessage) message).getDatastream();
return ContentModelHelper.Datastream.DATA_FILE.equals(datastream);
}
/**
* Applicability check which verifies that the data file is of an appropriate type and is either not present or newer
* than the derivative to be generated
*
* @param pid
* @return
* @throws FedoraException
*/
protected boolean isDatastreamApplicable(PID pid) throws FedoraException {
edu.unc.lib.dl.fedora.types.Datastream dataDoc
= managementClient.getDatastream(pid, Datastream.DATA_FILE.getName());
// Don't process if there is no original data
if (dataDoc == null) {
return false;
}
// Filter out objects with non-applicable mimetypes
if (!isMimetypeApplicable(pid, dataDoc)) {
return false;
}
edu.unc.lib.dl.fedora.types.Datastream derivDoc
= managementClient.getDatastream(pid, derivativeDatastream);
// No derivative present
if (derivDoc == null) {
return true;
}
// Derivative is older than the original data, need to reperform the enhancement
// Dates are in iso8601/UTC format, so lexographic string comparison is sufficient
return dataDoc.getCreateDate().compareTo(derivDoc.getCreateDate()) > 0;
}
/**
* Applicability check which only verifies that the data file exists and is of a mimetype appropriate for this
* service.
*
* @param pid
* @return
* @throws FedoraException
*/
protected boolean isApplicableType(PID pid) throws FedoraException {
edu.unc.lib.dl.fedora.types.Datastream dataDoc
= managementClient.getDatastream(pid, Datastream.DATA_FILE.getName());
// Don't process if there is no original data
if (dataDoc == null) {
return false;
}
// Filter out objects with non-applicable mimetypes
return isMimetypeApplicable(pid, dataDoc);
}
protected boolean isMimetypeApplicable(PID pid, edu.unc.lib.dl.fedora.types.Datastream dataDoc) {
// Filter out objects with non-applicable mimetypes
if (mimetypePattern != null) {
String mimetype = dataDoc.getMIMEType();
// If the mimetype from fedora isn't informative, retrieve source mimetype instead
if (OCTET_STREAM_MIMETYPE.equals(mimetype)) {
mimetype = tripleStoreQueryService.fetchFirstBySubjectAndPredicate(pid,
ContentModelHelper.CDRProperty.hasSourceMimeType.toString());
}
if (!mimetypePattern.matcher(mimetype).matches()){
return false;
}
}
return true;
}
@Override
public boolean isApplicable(EnhancementMessage message) throws EnhancementException {
String action = message.getQualifiedAction();
// Only need to check further if this is an ingest message or the DATA_FILE was changed
if (!(FedoraActions.INGEST.equals(action)
|| FedoraActions.MODIFY_DATASTREAM_BY_REFERENCE.equals(action)
|| FedoraActions.ADD_DATASTREAM.equals(action)
|| FedoraActions.MODIFY_DATASTREAM_BY_VALUE.equals(action)
|| APPLY_SERVICE_STACK.equals(action)
|| (APPLY_SERVICE.equals(action) && getClass().getName()
.equals(message.getServiceName())))) {
return false;
}
try {
// For a forced message, only check if the datastream is of an applicable type
if (message.isForce()) {
return isApplicableType(message.getPid());
}
// For other messages, determine whether the derivative exists or is stale
return isDatastreamApplicable(message.getPid());
} catch (FedoraException e) {
throw new EnhancementException("Failed to check if enhancement was applicable for " + message.getPid(), e);
}
}
}