Commit 81c43ab6 authored by acoburn's avatar acoburn
Browse files

rename service; add skeleton for dc conversions; move spring dsl to java

parent 0e24f390
......@@ -9,7 +9,7 @@ Services
* `acrepo-idiomatic`: Id Mapping Service: This maps a public ID to a (internal and typically much longer) fedora URI
* `acrepo-idiomatic-pgsql`: Id Mapping Service Database: This exposes a Postgres datastore for use with the Id Mapping service
* `acrepo-mint-service`: This mints random (public) URIs for use with fedora resources
* `acrepo-mods-xml-service`: This service translates Fedora RDF documents into MODS/XML
* `acrepo-xml-metadata`: This service translates Fedora RDF documents into MODS/XML or DC/XML
Building
--------
......
......@@ -54,7 +54,7 @@
<configfile finalname="/etc/edu.amherst.acdc.mint.cfg">mvn:edu.amherst.acdc/acrepo-mint-service/${project.version}/cfg/configuration</configfile>
</feature>
<feature name="acrepo-mods-xml-service" version="${project.version}" resolver="(orb)" start-level="50">
<feature name="acrepo-xml-metadata" version="${project.version}" resolver="(orb)" start-level="50">
<details>Installs the MODS/XML translation service</details>
<feature version="${camel.version}">camel</feature>
......@@ -63,9 +63,9 @@
<feature version="${camel.version}">camel-saxon</feature>
<feature version="${fcrepo-camel.version}">fcrepo-camel</feature>
<bundle>mvn:edu.amherst.acdc/acrepo-mods-xml-service/${project.version}</bundle>
<bundle>mvn:edu.amherst.acdc/acrepo-xml-metadata/${project.version}</bundle>
<configfile finalname="/etc/edu.amherst.acdc.mods.cfg">mvn:edu.amherst.acdc/acrepo-mods-xml-service/${project.version}/cfg/configuration</configfile>
<configfile finalname="/etc/edu.amherst.acdc.xml.metadata.cfg">mvn:edu.amherst.acdc/acrepo-xml-metadata/${project.version}/cfg/configuration</configfile>
</feature>
</features>
Amherst College MODS/XML transformation service
===============================================
Amherst College XML-based metadata transformation service
=========================================================
This service implements a translation service from Fedora RDF-based metadata
to a MODS/XML serialization. This translation relies on a pluggable XSLT 2.0
document.
to either a DC/XML or MODS/XML serialization. This translation relies on
pluggable XSLT 2.0 documents.
The service becomes available over HTTP on the configured port. For example,
in order to retrieve a MODS version of the resource `a/b/c`:
curl localhost:9070/mods/a/b/c
And the DC version:
curl localhost:9070/dc/a/b/c
Building
--------
......@@ -25,7 +34,7 @@ This project can be deployed in an OSGi container. For example using
command from its shell:
feature:repo-add mvn:edu.amherst.acdc/repository-services/LATEST/xml/features
feature:install acrepo-mods-xml-service
feature:install acrepo-xml-metadata
Or by copying the compiled bundle into `$KARAF_HOME/deploy`.
......@@ -33,22 +42,28 @@ Configuration
-------------
The application can be configured by creating the following configuration
file `$KARAF_HOME/etc/edu.amherst.acdc.mods.cfg`. The following values
file `$KARAF_HOME/etc/edu.amherst.acdc.xml.metadata.cfg`. The following values
are available for configuration:
The location of the XSLT document. This can be a file path (using the `file:` prefix)
In the event of failure, the maximum number of times a redelivery will be attempted.
error.maxRedeliveries=10
The location of the XSLT document for MODS. This can be a file path (using the `file:` prefix)
or an external URL (e.g. using a `http:` scheme). Without a prefix, the XSL file will
be loaded from the classpath.
mods.xslt=edu/amherst/acdc/mods/rdf2mods.xsl
mods.xslt=edu/amherst/acdc/xml/metadata/rdf2mods.xsl
The port on which the service is available
The location of the XSLT document for DC. This can be a file path (using the `file:` prefix)
or an external URL (e.g. using a `http:` scheme). Without a prefix, the XSL file will
be loaded from the classpath.
rest.port=9070
dc.xslt=edu/amherst/acdc/xml/metadata/rdf2dc.xsl
The URL prefix for the service
The port on which the service is available
rest.prefix=/mods
rest.port=9070
The fedora baseUrl value
......
......@@ -9,13 +9,13 @@
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>acrepo-mods-xml-service</artifactId>
<artifactId>acrepo-xml-metadata</artifactId>
<packaging>bundle</packaging>
<name>RDF to MODS/XML transformation service</name>
<name>RDF to XML (MODS and DC) transformation service</name>
<properties>
<osgi.private.packages>edu.amherst.acdc.mods</osgi.private.packages>
<osgi.private.packages>edu.amherst.acdc.xml.metadata</osgi.private.packages>
</properties>
<dependencies>
......@@ -101,7 +101,7 @@
<configuration>
<artifacts>
<artifact>
<file>src/main/cfg/edu.amherst.acdc.mods.cfg</file>
<file>src/main/cfg/edu.amherst.acdc.xml.metadata.cfg</file>
<type>cfg</type>
<classifier>configuration</classifier>
</artifact>
......
# The maximum number or redeliveries for any message
error.maxRedeliveries=10
# The port on which the service is made available
rest.port=9070
# The URL prefix for the service
rest.prefix=/mods
# The fedora baseUrl
fcrepo.baseUrl=localhost:8080/fcrepo/rest
# The location of the XSLT to convert RDF/XML to MODS/XML
mods.xslt=edu/amherst/acdc/mods/rdf2mods.xsl
# The location of the XSLT to convert RDF/XML to MODS/XML and DC/XML
mods.xslt=edu/amherst/acdc/xml/metadata/rdf2mods.xsl
dc.xslt=edu/amherst/acdc/xml/metadata/rdf2dc.xsl
/**
* 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.amherst.acdc.xml.metadata;
import static org.apache.camel.Exchange.HTTP_RESPONSE_CODE;
import static org.apache.camel.Exchange.CONTENT_TYPE;
import static org.fcrepo.camel.FcrepoHeaders.FCREPO_IDENTIFIER;
import static org.fcrepo.camel.FcrepoHeaders.FCREPO_BASE_URL;
import org.apache.camel.LoggingLevel;
import org.apache.camel.builder.RouteBuilder;
/**
* @author Aaron Coburn
*/
public class EventRouter extends RouteBuilder {
/**
* Configure the message route workflow.
*/
public void configure() throws Exception {
/**
* A generic error handler (specific to this RouteBuilder)
*/
onException(Exception.class)
.maximumRedeliveries("{{error.maxRedeliveries}}")
.log("Event Routing Error: ${routeId}");
from("jetty:http://0.0.0.0:{{rest.port}}/dc?" +
"matchOnUriPrefix=true&httpMethodRestrict=GET&sendServerVersion=false")
.routeId("DcTransformation")
.to("direct:getResource")
.filter(header(HTTP_RESPONSE_CODE).isEqualTo(200))
.setHeader(CONTENT_TYPE).constant("application/xml")
.convertBodyTo(org.w3c.dom.Document.class)
.log(LoggingLevel.INFO, "Converting resource to DC/XML: ${headers[CamelFcrepoIdentifier]}")
.to("xslt:{{dc.xslt}}?saxon=true");
from("jetty:http://0.0.0.0:{{rest.port}}/mods?" +
"matchOnUriPrefix=true&httpMethodRestrict=GET&sendServerVersion=false")
.routeId("ModsTransformation")
.to("direct:getResource")
.filter(header(HTTP_RESPONSE_CODE).isEqualTo(200))
.setHeader(CONTENT_TYPE).constant("application/xml")
.convertBodyTo(org.w3c.dom.Document.class)
.log(LoggingLevel.INFO, "Converting resource to MODS/XML: ${headers[CamelFcrepoIdentifier]}")
.to("xslt:{{mods.xslt}}?saxon=true");
from("direct:getResource")
.routeId("XmlTransformationCommon")
.removeHeader("breadcrumbId")
.removeHeader("Accept")
.removeHeader("User-Agent")
.setHeader(FCREPO_IDENTIFIER).simple("${headers[CamelHttpPath]}")
.setHeader(FCREPO_BASE_URL).simple("{{fcrepo.baseUrl}}")
.to("fcrepo:{{fcrepo.baseUrl}}?throwExceptionOnFailure=false");
}
}
......@@ -8,45 +8,18 @@
http://camel.apache.org/schema/blueprint http://camel.apache.org/schema/blueprint/camel-blueprint.xsd">
<!-- OSGI blueprint property placeholder -->
<cm:property-placeholder persistent-id="edu.amherst.acdc.mods" update-strategy="reload">
<cm:property-placeholder persistent-id="edu.amherst.acdc.xml.metadata" update-strategy="reload">
<cm:default-properties>
<cm:property name="rest.prefix" value="/mods"/>
<cm:property name="error.maxRedeliveries" value="10"/>
<cm:property name="rest.port" value="9070"/>
<cm:property name="mods.xslt" value="edu/amherst/acdc/mods/rdf2mods.xsl"/>
<cm:property name="mods.xslt" value="edu/amherst/acdc/xml/metadata/rdf2mods.xsl"/>
<cm:property name="dc.xslt" value="edu/amherst/acdc/xml/metadata/rdf2dc.xsl"/>
<cm:property name="fcrepo.baseUrl" value="localhost:8080/fcrepo/rest"/>
</cm:default-properties>
</cm:property-placeholder>
<camelContext xmlns="http://camel.apache.org/schema/blueprint" streamCache="false">
<route id="ModsTransformationRoute">
<from uri="jetty:http://0.0.0.0:{{rest.port}}{{rest.prefix}}?matchOnUriPrefix=true&amp;httpMethodRestrict=GET&amp;sendServerVersion=false"/>
<!-- clean up headers -->
<removeHeaders pattern="breadcrumbId"/>
<removeHeaders pattern="Accept"/>
<removeHeaders pattern="User-Agent"/>
<!-- set fcrepo headers -->
<setHeader headerName="CamelFcrepoIdentifier">
<simple>${headers[CamelHttpPath]}</simple>
</setHeader>
<setHeader headerName="CamelFcrepoBaseUrl">
<simple>{{fcrepo.baseUrl}}</simple>
</setHeader>
<!-- get the resource from the repository -->
<to uri="fcrepo:{{fcrepo.baseUrl}}?throwExceptionOnFailure=false"/>
<filter>
<simple>${headers[CamelHttpResponseCode]} == 200</simple>
<!-- if successful, translate it using the provided XSLT -->
<setHeader headerName="Content-Type">
<constant>application/xml</constant>
</setHeader>
<convertBodyTo type="org.w3c.dom.Document"/>
<log message="Converting resource to MODS/XML: ${headers[CamelFcrepoIdentifier]}"/>
<to uri="xslt:{{mods.xslt}}?saxon=true"/>
</filter>
</route>
<package>edu.amherst.acdc.xml.metadata</package>
</camelContext>
</blueprint>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
xmlns:rdfs='http://www.w3.org/2000/01/rdf-schema#'
xmlns:dcterms='http://purl.org/dc/terms/'
xmlns:dc='http://purl.org/dc/elements/1.1/'
xmlns:mods="http://www.loc.gov/mods/v3"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs rdf rdfs dc dcterms"
version="2.0">
<xsl:output indent="yes" method="xml"></xsl:output>
<xsl:param name="CamelFcrepoIdentifier"/>
<xsl:param name="CamelFcrepoBaseUrl"/>
<xsl:template match="/rdf:RDF/rdf:Description">
<xsl:if test="ends-with(@rdf:about, concat($CamelFcrepoBaseUrl, $CamelFcrepoIdentifier))">
<mods:mods>
<xsl:for-each select="dc:title">
<mods:titleInfo>
<mods:title><xsl:value-of select="normalize-space(text())"/></mods:title>
</mods:titleInfo>
</xsl:for-each>
<xsl:for-each select="dc:subject">
<mods:subject authority="lcsh">
<mods:topic>
<xsl:value-of select="normalize-space(text())"/>
</mods:topic>
</mods:subject>
</xsl:for-each>
<xsl:for-each select="dcterms:abstract">
<xsl:if test="string-length(normalize-space(text()))">
<mods:abstract><xsl:value-of select="normalize-space(text())"/></mods:abstract>
</xsl:if>
</xsl:for-each>
<xsl:for-each select="rdfs:comment">
<xsl:if test="string-length(normalize-space(text()))">
<mods:note><xsl:value-of select="normalize-space(text())"/></mods:note>
</xsl:if>
</xsl:for-each>
</mods:mods>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
......@@ -43,7 +43,7 @@
<module>acrepo-idiomatic</module>
<module>acrepo-karaf</module>
<module>acrepo-mint-service</module>
<module>acrepo-mods-xml-service</module>
<module>acrepo-xml-metadata</module>
</modules>
<dependencyManagement>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment