/**
* Copyright (c) Codice Foundation
* <p>
* This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser
* General Public License as published by the Free Software Foundation, either version 3 of the
* License, or any later version.
* <p>
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details. A copy of the GNU Lesser General Public License
* is distributed along with this program and can be found at
* <http://www.gnu.org/licenses/lgpl.html>.
*/
package ddf.catalog.transformer.resource;
import java.io.IOException;
import java.io.Serializable;
import java.util.Map;
import javax.activation.MimeType;
import javax.activation.MimeTypeParseException;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ddf.catalog.CatalogFramework;
import ddf.catalog.data.BinaryContent;
import ddf.catalog.data.Metacard;
import ddf.catalog.operation.ResourceRequest;
import ddf.catalog.operation.ResourceResponse;
import ddf.catalog.operation.impl.ResourceRequestById;
import ddf.catalog.resource.Resource;
import ddf.catalog.resource.ResourceNotFoundException;
import ddf.catalog.resource.ResourceNotSupportedException;
import ddf.catalog.resource.impl.ResourceImpl;
import ddf.catalog.transform.CatalogTransformerException;
import ddf.catalog.transform.MetacardTransformer;
/**
*
* This transformer uses the Catalog Framework to obtain and return the resource based on the
* metacard id.
*
*/
public class ResourceMetacardTransformer implements MetacardTransformer {
private static final Logger LOGGER = LoggerFactory.getLogger(ResourceMetacardTransformer.class);
private static final String DEFAULT_MIME_TYPE_STR = "application/octet-stream";
private CatalogFramework catalogFramework;
/**
* Construct instance with required framework to resolve the resource
*
* @param framework
*/
public ResourceMetacardTransformer(CatalogFramework framework) {
LOGGER.debug("constructing resource metacard transformer");
this.catalogFramework = framework;
}
@Override
public BinaryContent transform(Metacard metacard, Map<String, Serializable> arguments)
throws CatalogTransformerException {
LOGGER.trace("Entering resource ResourceMetacardTransformer.transform");
if (!isValid(metacard)) {
throw new CatalogTransformerException(
"Could not transform metacard to a resource because the metacard is not valid.");
}
if(StringUtils.isNotEmpty(metacard.getResourceSize())) {
arguments.put(Metacard.RESOURCE_SIZE, metacard.getResourceSize());
}
String id = metacard.getId();
LOGGER.debug("executing resource request with id '{}'", id);
final ResourceRequest resourceRequest = new ResourceRequestById(id, arguments);
ResourceResponse resourceResponse = null;
String sourceName = metacard.getSourceId();
if (StringUtils.isBlank(sourceName)) {
sourceName = catalogFramework.getId();
}
String resourceUriAscii = "";
if (metacard.getResourceURI() != null) {
resourceUriAscii = metacard.getResourceURI()
.toASCIIString();
}
try {
resourceResponse = catalogFramework.getResource(resourceRequest, sourceName);
} catch (IOException e) {
throw new CatalogTransformerException(retrieveResourceFailureMessage(id,
sourceName,
resourceUriAscii,
e.getMessage()), e);
} catch (ResourceNotFoundException e) {
throw new CatalogTransformerException(retrieveResourceFailureMessage(id,
sourceName,
resourceUriAscii,
e.getMessage()), e);
} catch (ResourceNotSupportedException e) {
throw new CatalogTransformerException(retrieveResourceFailureMessage(id,
sourceName,
resourceUriAscii,
e.getMessage()), e);
}
if (resourceResponse == null) {
throw new CatalogTransformerException(retrieveResourceFailureMessage(id,
sourceName,
resourceUriAscii));
}
Resource transformedContent = resourceResponse.getResource();
MimeType mimeType = transformedContent.getMimeType();
if (mimeType == null) {
try {
mimeType = new MimeType(DEFAULT_MIME_TYPE_STR);
// There is no method to set the MIME type, so in order to set it to our default
// one, we need to create a new object.
transformedContent = new ResourceImpl(transformedContent.getInputStream(),
mimeType,
transformedContent.getName());
} catch (MimeTypeParseException e) {
throw new CatalogTransformerException(
"Could not create default mime type upon null mimeType, for default mime type '"
+ DEFAULT_MIME_TYPE_STR + "'.",
e);
}
}
LOGGER.debug(
"Found mime type: '{}' for product of metacard with id: '{}'.\nGetting associated resource from input stream. \n",
mimeType,
id);
LOGGER.trace("Exiting resource transform for metacard id: '{}'", id);
return transformedContent;
}
/**
* Checks to see whether the given metacard is valid. If it is not valid, it will return false,
* otherwise true.
*
* @param metacard
* The metacard to be validated.
* @return boolean indicating validity.
*/
private boolean isValid(Metacard metacard) {
if (metacard == null) {
LOGGER.debug("Metacard cannot be null");
return false;
}
if (metacard.getId() == null) {
LOGGER.debug("Metacard id cannot be null");
return false;
}
return true;
}
private String retrieveResourceFailureMessage(final String id, final String sourceId,
final String resourceUri) {
return retrieveResourceFailureMessage(id, sourceId, resourceUri, null);
}
private String retrieveResourceFailureMessage(final String id, final String sourceId,
final String resourceUri, final String details) {
StringBuffer msg = new StringBuffer("Unable to retrieve resource.");
msg.append("\n\tMetacard id: " + (id == null ? "" : id));
msg.append("\n\tUri: " + (resourceUri == null ? "" : resourceUri));
msg.append("\n\tSource: " + (sourceId == null ? "" : sourceId));
msg.append("\n\tDetails: " + (details == null ? "" : details));
return msg.toString();
}
}