Skip to content

Commit

Permalink
Simplify type of LDPath transform result
Browse files Browse the repository at this point in the history
- Eliminate reflection
- Add type parameter to Transformation

Resolves: https://www.pivotaltracker.com/story/show/67483878
  • Loading branch information
ajs6f authored and Andrew Woods committed Mar 18, 2014
1 parent cd363f9 commit 45a169f
Show file tree
Hide file tree
Showing 11 changed files with 125 additions and 147 deletions.
Expand Up @@ -25,20 +25,25 @@
* Generic interface for transforming a resource's property dataset
* to an implementation-defined type
*/
public interface Transformation extends Function<Dataset, Object> {
public interface Transformation<T> extends Function<Dataset, T> {

/**
* Execute a transform on a dataset
* @param dataset
* @return
*/
@Override
Object apply(final Dataset dataset);
T apply(final Dataset dataset);

/**
* Get the Query the transformation is using
* @return
*/
InputStream getQuery();

/**
* @return a new Transform of this type, for use as a factory
*/
Transformation<T> newTransform(InputStream query);

}
Expand Up @@ -20,12 +20,11 @@
import org.fcrepo.transform.transformations.SparqlQueryTransform;

import javax.ws.rs.core.MediaType;

import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

import static com.google.common.base.Throwables.propagate;
import static org.apache.jena.riot.WebContent.contentTypeSPARQLQuery;
import static org.fcrepo.transform.transformations.LDPathTransform.APPLICATION_RDF_LDPATH;

Expand All @@ -34,24 +33,15 @@
*/
public class TransformationFactory {

private Map<String, Class<?>> mimeToTransform;
private Map<String, Transformation<?>> mimeToTransform = new HashMap<>();

/**
* Get a new TransformationFactory with the default classes
* @throws SecurityException
*/
public TransformationFactory() {
mimeToTransform = new HashMap<>();
mimeToTransform.put(contentTypeSPARQLQuery, SparqlQueryTransform.class);
mimeToTransform.put(APPLICATION_RDF_LDPATH, LDPathTransform.class);

}

/**
* Get a new TransformationFactory using the provided mapping
* @param mimeToTransform
*/
public TransformationFactory(final Map<String, Class<?>> mimeToTransform) {
this.mimeToTransform = mimeToTransform;
mimeToTransform.put(contentTypeSPARQLQuery, new SparqlQueryTransform(null));
mimeToTransform.put(APPLICATION_RDF_LDPATH, new LDPathTransform(null));
}

/**
Expand All @@ -61,26 +51,15 @@ public TransformationFactory(final Map<String, Class<?>> mimeToTransform) {
* @param inputStream
* @return
*/
public Transformation getTransform(final MediaType contentType,
final InputStream inputStream) {

if (mimeToTransform.containsKey(contentType.toString())) {
final Class<?> transform = mimeToTransform.get(contentType.toString());

if (Transformation.class.isAssignableFrom(transform)) {
try {
return (Transformation)(transform.getConstructor(InputStream.class).newInstance(inputStream));
} catch (NoSuchMethodException
| InvocationTargetException
| InstantiationException
| IllegalAccessException e) {
throw propagate(e);
}
}

@SuppressWarnings("unchecked")
// this suppression is in place representing the condition that the generator
// map actually maps the mimetypes proffered to legitimate Transformations for those mimetype
public <T> Transformation<T> getTransform(final MediaType contentType, final InputStream inputStream) {
final String mimeType = contentType.toString();
if (mimeToTransform.containsKey(mimeType)) {
return (Transformation<T>) mimeToTransform.get(contentType.toString()).newTransform(inputStream);
}

return null;

throw new UnsupportedOperationException(
"No transform type exists for media type " + mimeType + "!");
}
}
Expand Up @@ -60,9 +60,7 @@
import org.fcrepo.http.commons.api.rdf.HttpGraphSubjects;
import org.fcrepo.http.commons.session.InjectedSession;
import org.fcrepo.kernel.FedoraResource;
import org.fcrepo.transform.Transformation;
import org.fcrepo.transform.TransformationFactory;
import org.modeshape.jcr.api.JcrTools;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
Expand Down Expand Up @@ -93,38 +91,33 @@ public class FedoraTransform extends AbstractResource {
*
* @throws RepositoryException
* @throws java.io.IOException
* @throws SecurityException
*/
@PostConstruct
public void setUpRepositoryConfiguration() throws RepositoryException,
IOException {
public void setUpRepositoryConfiguration() throws RepositoryException, IOException {

if (transformationFactory == null) {
transformationFactory = new TransformationFactory();
}

final Session internalSession = sessions.getInternalSession();
try {
final JcrTools jcrTools = new JcrTools(true);

// register our CND
jcrTools.registerNodeTypes(internalSession, "ldpath.cnd");

// create the configuration base path
jcrTools.findOrCreateNode(internalSession,
"/fedora:system/fedora:transform", "fedora:configuration",
jcrTools.findOrCreateNode(internalSession, "/fedora:system/fedora:transform", "fedora:configuration",
"fedora:node_type_configuration");
final Node node =
jcrTools.findOrCreateNode(internalSession, CONFIGURATION_FOLDER
+ "default", NT_FOLDER, NT_FOLDER);
jcrTools.findOrCreateNode(internalSession, CONFIGURATION_FOLDER + "default", NT_FOLDER, NT_FOLDER);
LOGGER.debug("Transforming node: {}", node.getPath());
// register an initial demo program

// register an initial default program
if (!node.hasNode(NT_BASE)) {
final Node baseConfig = node.addNode(NT_BASE, NT_FILE);
jcrTools.uploadFile(internalSession, baseConfig.getPath(), getClass()
.getResourceAsStream(
"/ldpath/default/nt_base_ldpath_program.txt"));
jcrTools.uploadFile(internalSession, baseConfig.getPath(), getClass().getResourceAsStream(
"/ldpath/default/nt_base_ldpath_program.txt"));
}

internalSession.save();
} finally {
internalSession.logout();
Expand All @@ -150,14 +143,10 @@ public Object evaluateLdpathProgram(@PathParam("path")
final String path = toPath(pathList);
final FedoraResource object = nodeService.getObject(session, path);

final Transformation t =
getNodeTypeTransform(object.getNode(), program);

final Dataset propertiesDataset =
object.getPropertiesDataset(new HttpGraphSubjects(session,
FedoraNodes.class, uriInfo));
object.getPropertiesDataset(new HttpGraphSubjects(session, FedoraNodes.class, uriInfo));

return t.apply(propertiesDataset);
return getNodeTypeTransform(object.getNode(), program).apply(propertiesDataset);

} finally {
session.logout();
Expand Down Expand Up @@ -186,16 +175,12 @@ public Object evaluateTransform(@PathParam("path")

try {
final String path = toPath(pathList);
final FedoraResource object =
nodeService.getObject(session, path);
final FedoraResource object = nodeService.getObject(session, path);
final Dataset propertiesDataset =
object.getPropertiesDataset(new HttpGraphSubjects(
session, FedoraNodes.class, uriInfo));
object.getPropertiesDataset(new HttpGraphSubjects(session, FedoraNodes.class, uriInfo));

return transformationFactory.getTransform(contentType, requestBodyStream).apply(propertiesDataset);

final Transformation t =
transformationFactory.getTransform(contentType,
requestBodyStream);
return t.apply(propertiesDataset);
} finally {
session.logout();
}
Expand Down
Expand Up @@ -36,6 +36,7 @@
*/
@Component
public class TransformResources implements UriAwareResourceModelFactory {

@Override
public Model createModelForResource(final FedoraResource resource,
final UriInfo uriInfo, final GraphSubjects graphSubjects) throws RepositoryException {
Expand All @@ -47,7 +48,6 @@ public Model createModelForResource(final FedoraResource resource,
.getBaseUriBuilder().path(FedoraSparql.class).build()
.toASCIIString()));
}

return model;
}
}
Expand Up @@ -19,7 +19,6 @@
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.hp.hpl.jena.query.Dataset;
import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.RDFNode;
import com.hp.hpl.jena.rdf.model.Resource;

Expand All @@ -40,6 +39,7 @@
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static com.google.common.collect.Collections2.transform;
Expand All @@ -56,7 +56,7 @@
/**
* Utilities for working with LDPath
*/
public class LDPathTransform implements Transformation {
public class LDPathTransform implements Transformation<Map<String, Collection<Object>>> {

public static final String CONFIGURATION_FOLDER = "/fedora:system/fedora:transform/fedora:ldpath/";

Expand Down Expand Up @@ -136,7 +136,7 @@ public static LDPathTransform getNodeTypeTransform(final Node node,
}

@Override
public List<Map<String, Collection<Object>>> apply(final Dataset dataset) {
public Map<String, Collection<Object>> apply(final Dataset dataset) {
try {
final LDPath<RDFNode> ldpathForResource =
getLdpathResource(dataset);
Expand All @@ -148,7 +148,7 @@ public List<Map<String, Collection<Object>>> apply(final Dataset dataset) {
ldpathForResource.programQuery(context, new InputStreamReader(
query));

return ImmutableList.of(transformLdpathOutputToSomethingSerializable(wildcardCollection));
return transformLdpathOutputToSomethingSerializable(wildcardCollection);
} catch (final LDPathParseException e) {
throw new RuntimeException(e);
}
Expand All @@ -167,7 +167,7 @@ public boolean equals(final Object other) {

@Override
public int hashCode() {
return 3 + 5 * query.hashCode();
return Objects.hashCode(getQuery());
}

/**
Expand All @@ -177,13 +177,8 @@ public int hashCode() {
*/
private LDPath<RDFNode> getLdpathResource(final Dataset dataset) {

final Model model = unifyDatasetModel(dataset);
return new LDPath<>(new GenericJenaBackend(unifyDatasetModel(dataset)));

final GenericJenaBackend genericJenaBackend = new GenericJenaBackend(model);

final LDPath<RDFNode> ldpath = new LDPath<>(genericJenaBackend);

return ldpath;
}

/**
Expand Down Expand Up @@ -216,4 +211,9 @@ public Object apply(final Object input) {
return input;
}
};

@Override
public LDPathTransform newTransform(final InputStream query) {
return new LDPathTransform(query);
}
}
Expand Up @@ -22,18 +22,20 @@
import com.hp.hpl.jena.query.QueryExecutionFactory;
import com.hp.hpl.jena.query.QueryFactory;
import com.hp.hpl.jena.rdf.model.Model;

import org.apache.commons.io.IOUtils;
import org.fcrepo.transform.Transformation;

import java.io.IOException;
import java.io.InputStream;
import java.util.Objects;

import static org.fcrepo.kernel.rdf.SerializationUtils.unifyDatasetModel;

/**
* SPARQL Query-based transforms
*/
public class SparqlQueryTransform implements Transformation {
public class SparqlQueryTransform implements Transformation<QueryExecution> {

private final InputStream query;

Expand All @@ -55,7 +57,7 @@ public QueryExecution apply(final Dataset dataset) {
QueryFactory.create(IOUtils.toString(query));

return QueryExecutionFactory.create(sparqlQuery, model);
} catch (IOException e) {
} catch (final IOException e) {
throw new IllegalStateException(e);
}
}
Expand All @@ -66,14 +68,19 @@ public InputStream getQuery() {
}

@Override
public boolean equals(Object other) {
public boolean equals(final Object other) {
return other instanceof SparqlQueryTransform &&
query.equals(((SparqlQueryTransform)other).getQuery());
}

@Override
public int hashCode() {
return 5 + 7 * query.hashCode();
return Objects.hashCode(getQuery());
}

@Override
public SparqlQueryTransform newTransform(final InputStream query) {
return new SparqlQueryTransform(query);
}

}

0 comments on commit 45a169f

Please sign in to comment.