mirror of
https://github.com/DSpace/DSpace.git
synced 2025-10-23 18:03:11 +00:00
OAI 2.0 (a.k.a XOAI) integrated into DSpace 3.0 (squashed)
This commit is contained in:
@@ -1,40 +1,57 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-oai-api</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>DSpace OAI :: API and Implementation</name>
|
||||
<description>Libraries to support DSpace OAI Service Provider Webapplication</description>
|
||||
<?xml version="1.0"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>dspace-oai</artifactId>
|
||||
<groupId>org.dspace</groupId>
|
||||
<version>3.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>dspace-oai-api</artifactId>
|
||||
<name>DSpace OAI 2.0 :: API and Implementation</name>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
<description>XOAI API</description>
|
||||
|
||||
<!--
|
||||
A Parent POM that Maven inherits DSpace Default
|
||||
POM atrributes from.
|
||||
-->
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-oai</artifactId>
|
||||
<version>3.0-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-api-lang</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>oaicat</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.lyncode</groupId>
|
||||
<artifactId>xoai</artifactId>
|
||||
<version>2.2.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.solr</groupId>
|
||||
<artifactId>solr-solrj</artifactId>
|
||||
<version>3.3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<version>2.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<version>1.5.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.5.6</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<name>DSpace @ Lyncode</name>
|
||||
<email>dspace@lyncode.com</email>
|
||||
<organization>Lyncode</organization>
|
||||
<organizationUrl>http://www.lyncode.com</organizationUrl>
|
||||
</developer>
|
||||
</developers>
|
||||
</project>
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.app.didl;
|
||||
|
||||
import java.io.Serializable;
|
||||
/**
|
||||
* This class implements UUID version 4. The values for the various fields are
|
||||
* crypto random values set by the factory class UUIDFactory
|
||||
*
|
||||
* Development of this code was part of the aDORe repository project by the
|
||||
* Research Library of the Los Alamos National Laboratory.
|
||||
*
|
||||
* This code is based on the implementation of UUID version 4 (the one that
|
||||
* uses random/pseudo-random numbers by Ashraf Amrou of the Old Dominion University
|
||||
* (Aug 14, 2003)
|
||||
**/
|
||||
public final class UUID implements Serializable
|
||||
{
|
||||
private long hi;
|
||||
private long lo;
|
||||
|
||||
/**
|
||||
* Construct a Version 4 UUID object from another UUID object
|
||||
*
|
||||
* @param uuid
|
||||
* the UUID to use as a base for the new UUID
|
||||
**/
|
||||
public UUID(UUID uuid)
|
||||
{
|
||||
this.hi = uuid.hi;
|
||||
this.lo = uuid.lo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a Version 4 UUID object form the two given long values.
|
||||
* These values are (pseudo)random numbers (best if crypto quality)
|
||||
*
|
||||
* @param _hi
|
||||
* first long value
|
||||
*
|
||||
* @param _lo
|
||||
* second long value
|
||||
*
|
||||
**/
|
||||
public UUID(long _hi, long _lo)
|
||||
{
|
||||
this.hi = _hi;
|
||||
this.lo = _lo;
|
||||
// IETF variant (10)b
|
||||
lo &= 0x3FFFFFFFFFFFFFFFL; lo |= 0x8000000000000000L;
|
||||
// set multicast bit (so that it there is no chance it will clash
|
||||
// with other UUIDs generated based on real IEEE 802 addresses)
|
||||
lo |= 0x0000800000000000L;
|
||||
// version 4 (100)b: the one based on random/pseudo-random numbers
|
||||
hi &= 0xFFFFFFFFFFFF0FFFL; hi |= 0x0000000000004000L;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare UUID objects
|
||||
*
|
||||
* @param obj
|
||||
* the object to compare this UUID against
|
||||
*
|
||||
* @return true or false
|
||||
**/
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if(this == obj) // comparing to myself
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if(obj instanceof UUID)
|
||||
{
|
||||
UUID uuid = (UUID)obj;
|
||||
return (hi == uuid.hi && lo == uuid.lo);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a hash for the UUID
|
||||
*
|
||||
* @return hash code for the UUID
|
||||
*
|
||||
**/
|
||||
public int hashCode()
|
||||
{
|
||||
return Long.valueOf(hi ^ lo).hashCode();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Obtain a string representation of the UUID object
|
||||
*
|
||||
* @return the string representation of this UUID
|
||||
*
|
||||
**/
|
||||
public String toString()
|
||||
{
|
||||
return (/**"urn:uuid:" + **/
|
||||
hexDigits(hi >> 32, 4) // time_low: 4 hexOctet (8 hex digits)
|
||||
+ "-" +
|
||||
hexDigits(hi >> 16, 2) // time_mid: 2 hexOctet (4 hex digits)
|
||||
+ "-" +
|
||||
hexDigits(hi, 2) // time_high_and_version: 2 hexOctet (4 hex digits)
|
||||
+ "-" +
|
||||
hexDigits(lo >> 48, 2) // clock_seq_and_reserved: 1 hexOctet (2 hex digits) & clock_seq_low: 1 hexOctet (2 hex digits)
|
||||
+ "-" +
|
||||
hexDigits(lo, 6)); // node: 6 hexOctet (12 hex digits)
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain the Hex value of a given number of least significant octets
|
||||
* from a long value as a String
|
||||
*
|
||||
* @param lVal
|
||||
* the long value to retrieve octets from
|
||||
*
|
||||
* @param nHexOctets
|
||||
* number of hex octets to return
|
||||
*
|
||||
* @return hex value of least significant octets as a string
|
||||
*
|
||||
**/
|
||||
private static String hexDigits(long lVal, int nHexOctets) {
|
||||
long tmp = 1L << (nHexOctets * 2 * 4); // e.g., if nHexOctets is 2, tmp = (1 0000 0000 0000 0000)b & tmp - 1 = (1111 1111 1111 1111)b
|
||||
long result = lVal & (tmp - 1); // get ride of the uneeded most significant bits
|
||||
result = tmp | result; // make sure the digit at position (nDigits + 1) equals 1 (to preserve leading zeroes)
|
||||
return Long.toHexString(result).substring(1); // getride ot the digit at position nDigits + 1
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.app.didl;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Random;
|
||||
/**
|
||||
* Factory class for generating UUID version 4. All what this class does is
|
||||
* creating UUID version 4 objects using crypto-quality random numbers.
|
||||
*
|
||||
* Development of this code was part of the aDORe repository project by the
|
||||
* Research Library of the Los Alamos National Laboratory.
|
||||
*
|
||||
* This code is based on the implementation of UUID version 4 (the one that
|
||||
* uses random/pseudo-random numbers by Ashraf Amrou of the Old Dominion University
|
||||
* (Aug 14, 2003)
|
||||
*
|
||||
**/
|
||||
public final class UUIDFactory
|
||||
{
|
||||
/** Random number generator */
|
||||
private Random rand = null;
|
||||
|
||||
/** an instance */
|
||||
private static UUIDFactory generator = new UUIDFactory();
|
||||
|
||||
/** private constructor (Singleton class) */
|
||||
private UUIDFactory()
|
||||
{
|
||||
// crypto-quality random number generator
|
||||
rand = new SecureRandom();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Customers of this class call this method to generete new UUID objects
|
||||
*
|
||||
* @return a new UUID object
|
||||
*
|
||||
**/
|
||||
public static synchronized UUID generateUUID()
|
||||
{
|
||||
return new UUID(generator.rand.nextLong(),generator.rand.nextLong());
|
||||
}
|
||||
}
|
||||
@@ -1,239 +0,0 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.app.oai;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Date;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.dspace.app.didl.UUIDFactory;
|
||||
import org.dspace.content.Bitstream;
|
||||
import org.dspace.content.Bundle;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.search.HarvestedItemInfo;
|
||||
import org.dspace.storage.bitstore.BitstreamStorageManager;
|
||||
|
||||
import ORG.oclc.oai.server.crosswalk.Crosswalk;
|
||||
import ORG.oclc.oai.server.verb.CannotDisseminateFormatException;
|
||||
import ORG.oclc.oai.server.verb.ServerVerb;
|
||||
|
||||
/**
|
||||
* DSpace Item DIDL crosswalk.
|
||||
*
|
||||
* Development of this code was part of the aDORe repository project
|
||||
* by the Research Library of the Los Alamos National Laboratory.
|
||||
*
|
||||
* @author Henry Jerez
|
||||
* @author Los Alamos National Laboratory
|
||||
*/
|
||||
|
||||
public class DIDLCrosswalk extends Crosswalk
|
||||
{
|
||||
private static final Logger log = Logger.getLogger(DIDLCrosswalk.class);
|
||||
|
||||
/** default value if no oai.didl.maxresponse property is defined */
|
||||
public static final int MAXRESPONSE_INLINE_BITSTREAM = 0;
|
||||
|
||||
/** another crosswalk that will be used to generate the metadata section */
|
||||
private Crosswalk metadataCrosswalk;
|
||||
|
||||
public DIDLCrosswalk(Properties properties)
|
||||
{
|
||||
super("urn:mpeg:mpeg21:2002:02-DIDL-NS http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-21_schema_files/did/didl.xsd ");
|
||||
|
||||
// FIXME this should be injected from the configuration...
|
||||
// but it is better than duplicate the OAIDCCrosswalk code!
|
||||
metadataCrosswalk = new OAIDCCrosswalk(properties);
|
||||
}
|
||||
|
||||
|
||||
public boolean isAvailableFor(Object nativeItem)
|
||||
{
|
||||
// We have DC for everything
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public String createMetadata(Object nativeItem)
|
||||
throws CannotDisseminateFormatException
|
||||
{
|
||||
Item item = ((HarvestedItemInfo) nativeItem).item;
|
||||
|
||||
StringBuffer metadata = new StringBuffer();
|
||||
String itemhandle=item.getHandle();
|
||||
String strMaxSize = ConfigurationManager.getProperty("oai", "didl.maxresponse");
|
||||
int maxsize = MAXRESPONSE_INLINE_BITSTREAM;
|
||||
if (strMaxSize != null)
|
||||
{
|
||||
maxsize = Integer.parseInt(strMaxSize);
|
||||
}
|
||||
|
||||
String currdate=ServerVerb.createResponseDate(new Date());
|
||||
|
||||
metadata.append("<didl:DIDL ")
|
||||
.append(" xmlns:didl=\"urn:mpeg:mpeg21:2002:02-DIDL-NS\" ")
|
||||
.append(" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ")
|
||||
.append("xsi:schemaLocation=\"urn:mpeg:mpeg21:2002:02-DIDL-NS http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-21_schema_files/did/didl.xsd \">")
|
||||
.append ("<didl:DIDLInfo>")
|
||||
.append ("<dcterms:created xmlns:dcterms=\"http://purl.org/dc/terms/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://purl.org/dc/terms/ \">")
|
||||
.append (currdate)
|
||||
.append ("</dcterms:created> </didl:DIDLInfo>" )
|
||||
.append("<didl:Item id=\"")
|
||||
.append("uuid-" + UUIDFactory.generateUUID().toString()+"\">");
|
||||
metadata.append("<didl:Descriptor>")
|
||||
.append("<didl:Statement mimeType=\"application/xml; charset=utf-8\">")
|
||||
.append("<dii:Identifier xmlns:dii=\"urn:mpeg:mpeg21:2002:01-DII-NS\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"urn:mpeg:mpeg21:2002:01-DII-NS http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-21_schema_files/dii/dii.xsd\">").append("urn:hdl:").append(itemhandle)
|
||||
.append("</dii:Identifier>")
|
||||
.append("</didl:Statement>")
|
||||
.append("</didl:Descriptor>");
|
||||
metadata.append("<didl:Descriptor>")
|
||||
.append("<didl:Statement mimeType=\"application/xml; charset=utf-8\">");
|
||||
|
||||
// delegate the metadata section to another crosswalk
|
||||
metadata.append(metadataCrosswalk.createMetadata(nativeItem));
|
||||
|
||||
metadata
|
||||
.append("</didl:Statement>")
|
||||
.append("</didl:Descriptor>");
|
||||
|
||||
/**putfirst item here**/
|
||||
|
||||
|
||||
//**CYCLE HERE!!!!**//
|
||||
|
||||
try
|
||||
{
|
||||
Bundle[] bundles= item.getBundles("ORIGINAL");
|
||||
|
||||
if (bundles.length != 0)
|
||||
{
|
||||
/**cycle bundles**/
|
||||
for (int i = 0; i < bundles.length; i++)
|
||||
{
|
||||
int flag=0;
|
||||
Bitstream[] bitstreams = bundles[i].getBitstreams();
|
||||
|
||||
/**cycle bitstreams**/
|
||||
for (int k = 0; k < bitstreams.length ; k++)
|
||||
{
|
||||
// Skip internal types
|
||||
if (!bitstreams[k].getFormat().isInternal())
|
||||
{
|
||||
if (flag==0)
|
||||
{
|
||||
flag=1;
|
||||
}
|
||||
|
||||
metadata.append("<didl:Component id=" + "\"uuid-"+ UUIDFactory.generateUUID().toString() + "\">");
|
||||
|
||||
if (bitstreams[k].getSize()> maxsize)
|
||||
{
|
||||
metadata.append("<didl:Resource ref=\""+ConfigurationManager.getProperty("dspace.url")+"/bitstream/"+itemhandle+"/"+bitstreams[k].getSequenceID()+"/"+bitstreams[k].getName() );
|
||||
metadata.append("\" mimeType=\"");
|
||||
metadata.append(bitstreams[k].getFormat().getMIMEType());
|
||||
metadata.append("\">");
|
||||
metadata.append("</didl:Resource>");
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
metadata.append("<didl:Resource mimeType=\"");
|
||||
metadata.append(bitstreams[k].getFormat().getMIMEType());
|
||||
metadata.append("\" encoding=\"base64\">");
|
||||
|
||||
/*
|
||||
* Assume that size of in-line bitstreams will always be
|
||||
* smaller than MAXINT bytes
|
||||
*/
|
||||
int intSize = (int) bitstreams[k].getSize();
|
||||
|
||||
byte[] buffer = new byte[intSize];
|
||||
|
||||
Context contextl= new Context();
|
||||
InputStream is = BitstreamStorageManager.retrieve(contextl,bitstreams[k].getID());
|
||||
BufferedInputStream bis = new BufferedInputStream(is);
|
||||
try
|
||||
{
|
||||
bis.read(buffer);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (bis != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
bis.close();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
if (is != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
is.close();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
contextl.complete();
|
||||
|
||||
String encoding = new String(Base64.encodeBase64(buffer), "ASCII");
|
||||
metadata.append(encoding);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.error("Error creating resource didl", ex);
|
||||
|
||||
metadata.append("<didl:Resource ref=\"")
|
||||
.append(ConfigurationManager.getProperty("dspace.url"))
|
||||
.append("/bitstream/")
|
||||
.append(itemhandle).append("/").append(bitstreams[k].getSequenceID())
|
||||
.append("/").append(bitstreams[k].getName());
|
||||
metadata.append("\" mimeType=\"");
|
||||
metadata.append(bitstreams[k].getFormat().getMIMEType());
|
||||
metadata.append("\">");
|
||||
}
|
||||
|
||||
metadata.append("</didl:Resource>");
|
||||
}
|
||||
metadata.append("</didl:Component>");
|
||||
}
|
||||
/*end bitstream cycle*/
|
||||
}
|
||||
/*end bundle cycle*/
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SQLException sqle)
|
||||
{
|
||||
System.err.println("Caught exception:"+sqle.getCause());
|
||||
log.error("Database error", sqle);
|
||||
}
|
||||
|
||||
//**END CYCLE HERE **//
|
||||
|
||||
metadata.append("</didl:Item>")
|
||||
.append("</didl:DIDL>");
|
||||
|
||||
return metadata.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,933 +0,0 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.app.oai;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.text.ParseException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Properties;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.dspace.authorize.AuthorizeManager;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.Community;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.core.LogManager;
|
||||
import org.dspace.core.Utils;
|
||||
import org.dspace.handle.HandleManager;
|
||||
import org.dspace.search.Harvest;
|
||||
import org.dspace.search.HarvestedItemInfo;
|
||||
import org.dspace.eperson.Group;
|
||||
|
||||
import ORG.oclc.oai.server.catalog.AbstractCatalog;
|
||||
import ORG.oclc.oai.server.verb.BadArgumentException;
|
||||
import ORG.oclc.oai.server.verb.BadResumptionTokenException;
|
||||
import ORG.oclc.oai.server.verb.CannotDisseminateFormatException;
|
||||
import ORG.oclc.oai.server.verb.IdDoesNotExistException;
|
||||
import ORG.oclc.oai.server.verb.NoItemsMatchException;
|
||||
import ORG.oclc.oai.server.verb.NoMetadataFormatsException;
|
||||
import ORG.oclc.oai.server.verb.NoSetHierarchyException;
|
||||
import ORG.oclc.oai.server.verb.OAIInternalServerError;
|
||||
|
||||
/**
|
||||
* This class extends OAICat's AbstractCatalog base class to allow
|
||||
* harvesting of the metadata in DSpace via OAI-PMH 2.0.
|
||||
*
|
||||
* FIXME: Some CNRI Handle-specific stuff in here. Anyone wanting to use
|
||||
* something else will need to update this code, too. Sorry about that.
|
||||
*
|
||||
* @author Robert Tansley
|
||||
* @version $Revision$
|
||||
*/
|
||||
public class DSpaceOAICatalog extends AbstractCatalog
|
||||
{
|
||||
/** log4j logger */
|
||||
private static Logger log = Logger.getLogger(DSpaceOAICatalog.class);
|
||||
|
||||
/** Prefix that all our OAI identifiers have */
|
||||
public static final String OAI_ID_PREFIX = "oai:" + ConfigurationManager.getProperty("dspace.hostname") + ":";
|
||||
|
||||
/** Maximum number of records returned by one request */
|
||||
private final int MAX_RECORDS = ConfigurationManager.getIntProperty("oai","response.max-records", 100);
|
||||
|
||||
public DSpaceOAICatalog(Properties properties)
|
||||
{
|
||||
// Don't need to do anything
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a list of schemaLocation values associated with the specified
|
||||
* identifier.
|
||||
*
|
||||
* @param identifier
|
||||
* the OAI identifier
|
||||
* @return a Vector containing schemaLocation Strings
|
||||
* @exception OAIInternalServerError
|
||||
* signals an http status code 500 problem
|
||||
* @exception IdDoesNotExistException
|
||||
* the specified identifier can't be found
|
||||
* @exception NoMetadataFormatsException
|
||||
* the specified identifier was found but the item is flagged
|
||||
* as deleted and thus no schemaLocations (i.e.
|
||||
* metadataFormats) can be produced.
|
||||
*/
|
||||
public Vector getSchemaLocations(String identifier)
|
||||
throws OAIInternalServerError, IdDoesNotExistException,
|
||||
NoMetadataFormatsException
|
||||
{
|
||||
log.info(LogManager.getHeader(null, "oai_request",
|
||||
"verb=getSchemaLocations,identifier="
|
||||
+ ((identifier == null) ? "null" : identifier)));
|
||||
|
||||
HarvestedItemInfo itemInfo = null;
|
||||
Context context = null;
|
||||
|
||||
// Get the item from the DB
|
||||
try
|
||||
{
|
||||
context = new Context();
|
||||
|
||||
// All valid identifiers have the "oai:hostname:" prefix
|
||||
if (identifier != null && identifier.startsWith(OAI_ID_PREFIX))
|
||||
{
|
||||
itemInfo = Harvest.getSingle(context, identifier
|
||||
.substring(OAI_ID_PREFIX.length()), // Strip prefix to
|
||||
// get raw handle
|
||||
false);
|
||||
}
|
||||
}
|
||||
catch (SQLException se)
|
||||
{
|
||||
// Log the error
|
||||
log.warn(LogManager.getHeader(context, "database_error", ""), se);
|
||||
|
||||
// Stack trace loss as OAI Exception does not support cause
|
||||
throw new OAIInternalServerError(se.toString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (context != null)
|
||||
{
|
||||
context.abort();
|
||||
}
|
||||
}
|
||||
|
||||
if (itemInfo == null)
|
||||
{
|
||||
throw new IdDoesNotExistException(identifier);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (itemInfo.withdrawn)
|
||||
{
|
||||
throw new NoMetadataFormatsException();
|
||||
}
|
||||
else
|
||||
{
|
||||
return getRecordFactory().getSchemaLocations(itemInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a list of identifiers that satisfy the specified criteria
|
||||
*
|
||||
* @param from
|
||||
* beginning date using the proper granularity
|
||||
* @param until
|
||||
* ending date using the proper granularity
|
||||
* @param set
|
||||
* the set name or null if no such limit is requested
|
||||
* @param metadataPrefix
|
||||
* the OAI metadataPrefix or null if no such limit is requested
|
||||
* @return a Map object containing entries for "headers" and "identifiers"
|
||||
* Iterators (both containing Strings) as well as an optional
|
||||
* "resumptionMap" Map. It may seem strange for the map to include
|
||||
* both "headers" and "identifiers" since the identifiers can be
|
||||
* obtained from the headers. This may be true, but
|
||||
* AbstractCatalog.listRecords() can operate quicker if it doesn't
|
||||
* need to parse identifiers from the XML headers itself. Better
|
||||
* still, do like I do below and override
|
||||
* AbstractCatalog.listRecords(). AbstractCatalog.listRecords() is
|
||||
* relatively inefficient because given the list of identifiers, it
|
||||
* must call getRecord() individually for each as it constructs its
|
||||
* response. It's much more efficient to construct the entire
|
||||
* response in one fell swoop by overriding listRecords() as I've
|
||||
* done here.
|
||||
* @exception OAIInternalServerError
|
||||
* signals an http status code 500 problem
|
||||
* @exception NoSetHierarchyException
|
||||
* the repository doesn't support sets.
|
||||
* @exception CannotDisseminateFormatException
|
||||
* the metadata format specified is not supported by your
|
||||
* repository.
|
||||
*/
|
||||
public Map listIdentifiers(String from, String until, String set,
|
||||
String metadataPrefix) throws OAIInternalServerError,
|
||||
NoSetHierarchyException, NoItemsMatchException,
|
||||
CannotDisseminateFormatException, BadArgumentException
|
||||
{
|
||||
log
|
||||
.info(LogManager.getHeader(null, "oai_request",
|
||||
"verb=listIdentifiers,from="
|
||||
+ ((from == null) ? "null" : from)
|
||||
+ ",until="
|
||||
+ ((until == null) ? "null" : until)
|
||||
+ ",set="
|
||||
+ ((set == null) ? "null" : set)
|
||||
+ ",metadataPrefix="
|
||||
+ ((metadataPrefix == null) ? "null"
|
||||
: metadataPrefix)));
|
||||
|
||||
// We can produce oai_dc and simple DC for all items, so just return IDs
|
||||
Context context = null;
|
||||
|
||||
// Lists to put results in
|
||||
List<String> headers = new LinkedList<String>();
|
||||
List<String> identifiers = new LinkedList<String>();
|
||||
|
||||
try
|
||||
{
|
||||
context = new Context();
|
||||
|
||||
// Get the relevant OAIItemInfo objects to make headers
|
||||
DSpaceObject scope = resolveSet(context, set);
|
||||
boolean includeAll = ConfigurationManager.getBooleanProperty("oai", "harvest.includerestricted.oai", true);
|
||||
// Warning: In large repositories, setting harvest.includerestricted.oai to false may cause
|
||||
// performance problems as all items will need to have their authorization permissions checked,
|
||||
// but because we haven't implemented resumption tokens in ListIdentifiers, ALL items will
|
||||
// need checking whenever a ListIdentifiers request is made.
|
||||
List<HarvestedItemInfo> itemInfos = Harvest.harvest(context, scope, from, until, 0, 0, // Everything
|
||||
// for
|
||||
// now
|
||||
!includeAll, true, true, includeAll);
|
||||
|
||||
// No Item objects, but we need to know collections they're in and
|
||||
// withdrawn items
|
||||
if (itemInfos.size() == 0)
|
||||
{
|
||||
log.info(LogManager.getHeader(null, "oai_error",
|
||||
"no_items_match"));
|
||||
throw new NoItemsMatchException();
|
||||
}
|
||||
|
||||
// Build up lists of headers and identifiers
|
||||
Iterator<HarvestedItemInfo> i = itemInfos.iterator();
|
||||
|
||||
while (i.hasNext())
|
||||
{
|
||||
HarvestedItemInfo itemInfo = i.next();
|
||||
|
||||
String[] header = getRecordFactory().createHeader(itemInfo);
|
||||
|
||||
headers.add(header[0]);
|
||||
identifiers.add(header[1]);
|
||||
}
|
||||
}
|
||||
catch (SQLException se)
|
||||
{
|
||||
// Log the error
|
||||
log.warn(LogManager.getHeader(context, "database_error", ""), se);
|
||||
|
||||
// Stack trace loss as OAI Exception does not support cause
|
||||
throw new OAIInternalServerError(se.toString());
|
||||
}
|
||||
catch (ParseException pe)
|
||||
{
|
||||
// Stack trace loss as OAI Exception does not support cause
|
||||
throw new OAIInternalServerError(pe.toString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (context != null)
|
||||
{
|
||||
context.abort();
|
||||
}
|
||||
}
|
||||
|
||||
// Put results in form needed to return
|
||||
Map<String, Iterator<String>> results = new HashMap<String, Iterator<String>>();
|
||||
results.put("headers", headers.iterator());
|
||||
results.put("identifiers", identifiers.iterator());
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the next set of identifiers associated with the resumptionToken
|
||||
*
|
||||
* @param resumptionToken
|
||||
* implementation-dependent format taken from the previous
|
||||
* listIdentifiers() Map result.
|
||||
* @return a Map object containing entries for "headers" and "identifiers"
|
||||
* Iterators (both containing Strings) as well as an optional
|
||||
* "resumptionMap" Map.
|
||||
* @exception BadResumptionTokenException
|
||||
* the value of the resumptionToken is invalid or expired.
|
||||
* @exception OAIInternalServerError
|
||||
* signals an http status code 500 problem
|
||||
*/
|
||||
public Map listIdentifiers(String resumptionToken)
|
||||
throws BadResumptionTokenException, OAIInternalServerError
|
||||
{
|
||||
// Resumption tokens not yet supported
|
||||
throw new BadResumptionTokenException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the specified metadata for the specified identifier
|
||||
*
|
||||
* @param identifier
|
||||
* the OAI identifier
|
||||
* @param metadataPrefix
|
||||
* the OAI metadataPrefix
|
||||
* @return the <record/>portion of the XML response.
|
||||
* @exception OAIInternalServerError
|
||||
* signals an http status code 500 problem
|
||||
* @exception CannotDisseminateFormatException
|
||||
* the metadataPrefix is not supported by the item.
|
||||
* @exception IdDoesNotExistException
|
||||
* the identifier wasn't found
|
||||
*/
|
||||
public String getRecord(String identifier, String metadataPrefix)
|
||||
throws OAIInternalServerError, CannotDisseminateFormatException,
|
||||
IdDoesNotExistException
|
||||
{
|
||||
log
|
||||
.info(LogManager.getHeader(null, "oai_request",
|
||||
"verb=getRecord,identifier="
|
||||
+ ((identifier == null) ? "null" : identifier)
|
||||
+ ",metadataPrefix="
|
||||
+ ((metadataPrefix == null) ? "null"
|
||||
: metadataPrefix)));
|
||||
|
||||
Context context = null;
|
||||
String record = null;
|
||||
HarvestedItemInfo itemInfo = null;
|
||||
|
||||
// First get the item from the DB
|
||||
try
|
||||
{
|
||||
// Valid IDs start with oai:hostname:
|
||||
if (identifier != null && identifier.startsWith(OAI_ID_PREFIX))
|
||||
{
|
||||
context = new Context();
|
||||
|
||||
/*
|
||||
* Try and get the item. the .substring() is to strip the
|
||||
* oai:(hostname): prefix to get the raw handle
|
||||
*/
|
||||
itemInfo = Harvest.getSingle(context, identifier
|
||||
.substring(OAI_ID_PREFIX.length()), true);
|
||||
}
|
||||
|
||||
if (itemInfo == null)
|
||||
{
|
||||
log.info(LogManager.getHeader(null, "oai_error",
|
||||
"id_does_not_exist"));
|
||||
throw new IdDoesNotExistException(identifier);
|
||||
}
|
||||
|
||||
boolean includeAll = ConfigurationManager.getBooleanProperty("oai", "harvest.includerestricted.oai", true);
|
||||
|
||||
if (!includeAll)
|
||||
{
|
||||
Group[] authorizedGroups = AuthorizeManager.getAuthorizedGroups(context, itemInfo.item, Constants.READ);
|
||||
boolean authorized = false;
|
||||
for (int i = 0; i < authorizedGroups.length; i++)
|
||||
{
|
||||
if ((authorizedGroups[i].getID() == 0) && (!authorized))
|
||||
{
|
||||
authorized = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!authorized)
|
||||
{
|
||||
log.info(LogManager.getHeader(null, "oai_error",
|
||||
"id_not_accessible"));
|
||||
throw new IdDoesNotExistException(identifier);
|
||||
}
|
||||
}
|
||||
|
||||
String schemaURL = getCrosswalks().getSchemaURL(metadataPrefix);
|
||||
|
||||
if (schemaURL == null)
|
||||
{
|
||||
log.info(LogManager.getHeader(null, "oai_error",
|
||||
"cannot_disseminate_format"));
|
||||
throw new CannotDisseminateFormatException(metadataPrefix);
|
||||
}
|
||||
|
||||
record = getRecordFactory().create(itemInfo, schemaURL,
|
||||
metadataPrefix);
|
||||
}
|
||||
catch (SQLException se)
|
||||
{
|
||||
// Log the error
|
||||
log.warn(LogManager.getHeader(context, "database_error", ""), se);
|
||||
|
||||
// Stack trace loss as OAI Exception does not support cause
|
||||
throw new OAIInternalServerError(se.toString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (context != null)
|
||||
{
|
||||
context.abort();
|
||||
}
|
||||
}
|
||||
|
||||
return record;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a list of records that satisfy the specified criteria. Note,
|
||||
* though, that unlike the other OAI verb type methods implemented here,
|
||||
* both of the listRecords methods are already implemented in
|
||||
* AbstractCatalog rather than abstracted. This is because it is possible to
|
||||
* implement ListRecords as a combination of ListIdentifiers and GetRecord
|
||||
* combinations. Nevertheless, I suggest that you override both the
|
||||
* AbstractCatalog.listRecords methods here since it will probably improve
|
||||
* the performance if you create the response in one fell swoop rather than
|
||||
* construct it one GetRecord at a time.
|
||||
*
|
||||
* @param from
|
||||
* beginning date using the proper granularity
|
||||
* @param until
|
||||
* ending date using the proper granularity
|
||||
* @param set
|
||||
* the set name or null if no such limit is requested
|
||||
* @param metadataPrefix
|
||||
* the OAI metadataPrefix or null if no such limit is requested
|
||||
* @return a Map object containing entries for a "records" Iterator object
|
||||
* (containing XML <record/>Strings) and an optional
|
||||
* "resumptionMap" Map.
|
||||
* @exception OAIInternalServerError
|
||||
* signals an http status code 500 problem
|
||||
* @exception NoSetHierarchyException
|
||||
* The repository doesn't support sets.
|
||||
* @exception CannotDisseminateFormatException
|
||||
* the metadataPrefix isn't supported by the item.
|
||||
*/
|
||||
public Map listRecords(String from, String until, String set,
|
||||
String metadataPrefix) throws OAIInternalServerError,
|
||||
NoSetHierarchyException, CannotDisseminateFormatException,
|
||||
NoItemsMatchException, BadArgumentException
|
||||
{
|
||||
log
|
||||
.info(LogManager.getHeader(null, "oai_request",
|
||||
"verb=listRecords,from="
|
||||
+ ((from == null) ? "null" : from)
|
||||
+ ",until="
|
||||
+ ((until == null) ? "null" : until)
|
||||
+ ",set="
|
||||
+ ((set == null) ? "null" : set)
|
||||
+ ",metadataPrefix="
|
||||
+ ((metadataPrefix == null) ? "null"
|
||||
: metadataPrefix)));
|
||||
|
||||
Map m = doRecordHarvest(from, until, set, metadataPrefix, 0);
|
||||
|
||||
// Null means bad metadata prefix
|
||||
if (m == null)
|
||||
{
|
||||
log.info(LogManager.getHeader(null, "oai_error",
|
||||
"cannot_disseminate_format"));
|
||||
throw new CannotDisseminateFormatException(metadataPrefix);
|
||||
}
|
||||
|
||||
// If there were zero results, return the appropriate error
|
||||
Iterator i = (Iterator) m.get("records");
|
||||
|
||||
if ((i == null) || !i.hasNext())
|
||||
{
|
||||
log.info(LogManager.getHeader(null, "oai_error", "no_items_match"));
|
||||
throw new NoItemsMatchException();
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the next set of records associated with the resumptionToken
|
||||
*
|
||||
* @param resumptionToken
|
||||
* implementation-dependent format taken from the previous
|
||||
* listRecords() Map result.
|
||||
* @return a Map object containing entries for "headers" and "identifiers"
|
||||
* Iterators (both containing Strings) as well as an optional
|
||||
* "resumptionMap" Map.
|
||||
* @exception OAIInternalServerError
|
||||
* signals an http status code 500 problem
|
||||
* @exception BadResumptionTokenException
|
||||
* the value of the resumptionToken argument is invalid or
|
||||
* expired.
|
||||
*/
|
||||
public Map listRecords(String resumptionToken)
|
||||
throws BadResumptionTokenException, OAIInternalServerError
|
||||
{
|
||||
log.info(LogManager.getHeader(null, "oai_request",
|
||||
"verb=listRecords,resumptionToken=" + resumptionToken));
|
||||
|
||||
/*
|
||||
* FIXME: This may return zero records if the previous harvest returned
|
||||
* a number of records that's an exact multiple of MAX_RECORDS. I hope
|
||||
* that's OK.
|
||||
*/
|
||||
Object[] params = decodeResumptionToken(resumptionToken);
|
||||
Integer offset = (Integer) params[4];
|
||||
|
||||
Map m = null;
|
||||
|
||||
/*
|
||||
* We catch BadArgumentExceptions here, because doRecordHarvest() throws
|
||||
* BadArgumentExcpetions when the set spec is bad. set spec bad == bad
|
||||
* resumption token.
|
||||
*/
|
||||
try
|
||||
{
|
||||
m = doRecordHarvest((String) params[0], (String) params[1],
|
||||
(String) params[2], (String) params[3], offset.intValue());
|
||||
}
|
||||
catch (BadArgumentException bae)
|
||||
{
|
||||
m = null;
|
||||
}
|
||||
|
||||
// null result means a problem -> bad resumption token
|
||||
if (m == null)
|
||||
{
|
||||
log.info(LogManager.getHeader(null, "oai_error",
|
||||
"bad_resumption_token"));
|
||||
throw new BadResumptionTokenException();
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to do the actual harvest of records
|
||||
*
|
||||
* @param from
|
||||
* OAI 'from' parameter
|
||||
* @param until
|
||||
* OAI 'until' parameter
|
||||
* @param set
|
||||
* OAI 'set' parameter
|
||||
* @param metadataPrefix
|
||||
* OAI 'metadataPrefix' parameter
|
||||
* @param offset
|
||||
* where to start this harvest
|
||||
*
|
||||
* @return the Map for listRecords to return, or null if the metadataPrefix
|
||||
* is invalid
|
||||
*/
|
||||
private Map doRecordHarvest(String from, String until, String set,
|
||||
String metadataPrefix, int offset) throws OAIInternalServerError,
|
||||
BadArgumentException
|
||||
{
|
||||
Context context = null;
|
||||
String schemaURL = getCrosswalks().getSchemaURL(metadataPrefix);
|
||||
Map results = new HashMap();
|
||||
|
||||
if (schemaURL == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// List to put results in
|
||||
List<String> records = new LinkedList<String>();
|
||||
|
||||
try
|
||||
{
|
||||
context = new Context();
|
||||
|
||||
// Get the relevant HarvestedItemInfo objects to make headers
|
||||
DSpaceObject scope = resolveSet(context, set);
|
||||
boolean includeAll = ConfigurationManager.getBooleanProperty("oai", "harvest.includerestricted.oai", true);
|
||||
List<HarvestedItemInfo> itemInfos = Harvest.harvest(context, scope, from, until,
|
||||
offset, MAX_RECORDS, // Limit amount returned from one
|
||||
// request
|
||||
true, true, true, includeAll); // Need items, containers + withdrawals
|
||||
|
||||
// Build list of XML records from item info objects
|
||||
int ignore = 0;
|
||||
for (HarvestedItemInfo itemInfo : itemInfos)
|
||||
{
|
||||
try
|
||||
{
|
||||
String recordXML = getRecordFactory().create(itemInfo, schemaURL, metadataPrefix);
|
||||
records.add(recordXML);
|
||||
}
|
||||
catch (CannotDisseminateFormatException cdfe)
|
||||
{
|
||||
/*
|
||||
* FIXME: I've a feeling a
|
||||
* "CannotDisseminateFormatException" should be discarded
|
||||
* here - it's OK if some records in the requested date
|
||||
* range don't have the requested metadata format available.
|
||||
* I'll just log it for now.
|
||||
*/
|
||||
ignore++;
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug(LogManager.getHeader(context, "oai_warning",
|
||||
"Couldn't disseminate " + metadataPrefix
|
||||
+ " for " + itemInfo.handle));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Put results in form needed to return
|
||||
results.put("records", records.iterator());
|
||||
|
||||
log.info(LogManager.getHeader(context, "oai_harvest", "results=" + records.size() + ", ignore=" + ignore));
|
||||
|
||||
// If we have MAX_RECORDS records, we need to provide a resumption
|
||||
// token
|
||||
if ((records.size() + ignore) >= MAX_RECORDS)
|
||||
{
|
||||
String resumptionToken = makeResumptionToken(from, until, set,
|
||||
metadataPrefix, offset + MAX_RECORDS);
|
||||
|
||||
if (log.isDebugEnabled())
|
||||
{
|
||||
log.debug(LogManager
|
||||
.getHeader(context, "made_resumption_token",
|
||||
"token=" + resumptionToken));
|
||||
}
|
||||
|
||||
results.put("resumptionMap", getResumptionMap(resumptionToken));
|
||||
|
||||
//results.put("resumptionToken", resumptionToken);
|
||||
}
|
||||
}
|
||||
catch (SQLException se)
|
||||
{
|
||||
// Log the error
|
||||
log.warn(LogManager.getHeader(context, "database_error", ""), se);
|
||||
|
||||
// Stack trace loss as OAI Exception does not support cause
|
||||
throw new OAIInternalServerError(se.toString());
|
||||
}
|
||||
catch (ParseException pe)
|
||||
{
|
||||
// Stack trace loss as OAI Exception does not support cause
|
||||
throw new OAIInternalServerError(pe.toString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (context != null)
|
||||
{
|
||||
context.abort();
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a list of sets that satisfy the specified criteria
|
||||
*
|
||||
* @return a Map object containing "sets" Iterator object (contains
|
||||
* <setSpec/>XML Strings) as well as an optional resumptionMap Map.
|
||||
* @exception NoSetHierarchyException
|
||||
* signals an http status code 400 problem
|
||||
* @exception OAIInternalServerError
|
||||
* signals an http status code 500 problem
|
||||
*/
|
||||
public Map listSets() throws NoSetHierarchyException,
|
||||
OAIInternalServerError
|
||||
{
|
||||
log.info(LogManager.getHeader(null, "oai_request", "verb=listSets"));
|
||||
|
||||
Context context = null;
|
||||
|
||||
// List to put results in
|
||||
List<String> sets = new LinkedList<String>();
|
||||
|
||||
try
|
||||
{
|
||||
context = new Context();
|
||||
|
||||
Collection[] allCols = Collection.findAll(context);
|
||||
StringBuffer spec = null;
|
||||
for (int i = 0; i < allCols.length; i++)
|
||||
{
|
||||
spec = new StringBuffer("<set><setSpec>hdl_");
|
||||
spec.append(allCols[i].getHandle().replace('/', '_'));
|
||||
spec.append("</setSpec>");
|
||||
String collName = allCols[i].getMetadata("name");
|
||||
if(collName != null)
|
||||
{
|
||||
spec.append("<setName>");
|
||||
spec.append(Utils.addEntities(collName));
|
||||
spec.append("</setName>");
|
||||
}
|
||||
else
|
||||
{
|
||||
spec.append("<setName />");
|
||||
// Warn that there is an error of a null set name
|
||||
log.info(LogManager.getHeader(null, "oai_error",
|
||||
"null_set_name_for_set_id_" + allCols[i].getHandle()));
|
||||
}
|
||||
spec.append("</set>");
|
||||
sets.add(spec.toString());
|
||||
}
|
||||
|
||||
Community[] allComs = Community.findAll(context);
|
||||
for (int i = 0; i < allComs.length; i++)
|
||||
{
|
||||
spec = new StringBuffer("<set><setSpec>hdl_");
|
||||
spec.append(allComs[i].getHandle().replace('/', '_'));
|
||||
spec.append("</setSpec>");
|
||||
String commName = allComs[i].getMetadata("name");
|
||||
if(commName != null)
|
||||
{
|
||||
spec.append("<setName>");
|
||||
spec.append(Utils.addEntities(commName));
|
||||
spec.append("</setName>");
|
||||
}
|
||||
else
|
||||
{
|
||||
spec.append("<setName />");
|
||||
// Warn that there is an error of a null set name
|
||||
log.info(LogManager.getHeader(null, "oai_error",
|
||||
"null_set_name_for_set_id_" + allComs[i].getHandle()));
|
||||
}
|
||||
spec.append("</set>");
|
||||
sets.add(spec.toString());
|
||||
}
|
||||
}
|
||||
catch (SQLException se)
|
||||
{
|
||||
// Log the error
|
||||
log.warn(LogManager.getHeader(context, "database_error", ""), se);
|
||||
|
||||
// Stack trace loss as OAI Exception does not support cause
|
||||
throw new OAIInternalServerError(se.toString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (context != null)
|
||||
{
|
||||
context.abort();
|
||||
}
|
||||
}
|
||||
|
||||
// Put results in form needed to return
|
||||
Map<String, Iterator<String>> results = new HashMap<String, Iterator<String>>();
|
||||
results.put("sets", sets.iterator());
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the next set of sets associated with the resumptionToken
|
||||
*
|
||||
* @param resumptionToken
|
||||
* implementation-dependent format taken from the previous
|
||||
* listSets() Map result.
|
||||
* @return a Map object containing "sets" Iterator object (contains
|
||||
* <setSpec/>XML Strings) as well as an optional resumptionMap Map.
|
||||
* @exception BadResumptionTokenException
|
||||
* the value of the resumptionToken is invalid or expired.
|
||||
* @exception OAIInternalServerError
|
||||
* signals an http status code 500 problem
|
||||
*/
|
||||
public Map listSets(String resumptionToken)
|
||||
throws BadResumptionTokenException, OAIInternalServerError
|
||||
{
|
||||
// Resumption tokens not yet supported
|
||||
throw new BadResumptionTokenException();
|
||||
}
|
||||
|
||||
/**
|
||||
* close the repository
|
||||
*/
|
||||
public void close()
|
||||
{
|
||||
}
|
||||
|
||||
// ******************************************
|
||||
// Internal DSpace utility methods below here
|
||||
// ******************************************
|
||||
|
||||
/**
|
||||
* Get the community or collection signified by a set spec
|
||||
*
|
||||
* @param context
|
||||
* DSpace context object
|
||||
* @param set
|
||||
* OAI set spec
|
||||
* @return the corresponding community or collection, or null if no set
|
||||
* provided
|
||||
*/
|
||||
private DSpaceObject resolveSet(Context context, String set)
|
||||
throws SQLException, BadArgumentException
|
||||
{
|
||||
if (set == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
DSpaceObject o = null;
|
||||
|
||||
/*
|
||||
* set specs are in form hdl_123.456_789 corresponding to
|
||||
* hdl:123.456/789
|
||||
*/
|
||||
if (set.startsWith("hdl_"))
|
||||
{
|
||||
// Looks OK so far... turn second _ into /
|
||||
String handle = set.substring(4).replace('_', '/');
|
||||
o = HandleManager.resolveToObject(context, handle);
|
||||
}
|
||||
|
||||
// If it corresponds to a collection or a community, that's the set we
|
||||
// want
|
||||
if ((o != null) &&
|
||||
((o instanceof Collection) || (o instanceof Community)))
|
||||
{
|
||||
return o;
|
||||
}
|
||||
|
||||
// Handle is either non-existent, or corresponds to a non-collection
|
||||
// Either way, a bad set spec, ergo a bad argument
|
||||
throw new BadArgumentException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a resumption token. The relevant parameters for the harvest are
|
||||
* put in a
|
||||
*
|
||||
* @param from
|
||||
* OAI 'from' parameter
|
||||
* @param until
|
||||
* OAI 'until' parameter
|
||||
* @param set
|
||||
* OAI 'set' parameter
|
||||
* @param prefix
|
||||
* OAI 'metadataPrefix' parameter
|
||||
* @param offset
|
||||
* where to start the next harvest
|
||||
*
|
||||
* @return the appropriate resumption token
|
||||
*/
|
||||
private String makeResumptionToken(String from, String until, String set,
|
||||
String prefix, int offset)
|
||||
{
|
||||
StringBuffer token = new StringBuffer();
|
||||
|
||||
if (from != null)
|
||||
{
|
||||
token.append(from);
|
||||
}
|
||||
|
||||
token.append("/");
|
||||
|
||||
if (until != null)
|
||||
{
|
||||
token.append(until);
|
||||
}
|
||||
|
||||
token.append("/");
|
||||
|
||||
if (set != null)
|
||||
{
|
||||
token.append(set);
|
||||
}
|
||||
|
||||
token.append("/");
|
||||
|
||||
if (prefix != null)
|
||||
{
|
||||
token.append(prefix);
|
||||
}
|
||||
|
||||
token.append("/");
|
||||
token.append(String.valueOf(offset));
|
||||
|
||||
return (token.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the information out of a resumption token
|
||||
*
|
||||
* @param token
|
||||
* the resumption token
|
||||
* @return a 5-long array of Objects; 4 Strings (from, until, set, prefix)
|
||||
* and an Integer (the offset)
|
||||
*/
|
||||
private Object[] decodeResumptionToken(String token)
|
||||
throws BadResumptionTokenException
|
||||
{
|
||||
Object[] obj = new Object[5];
|
||||
StringTokenizer st = new StringTokenizer(token, "/", true);
|
||||
|
||||
try
|
||||
{
|
||||
// Extract from, until, set, prefix
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (!st.hasMoreTokens())
|
||||
{
|
||||
throw new BadResumptionTokenException();
|
||||
}
|
||||
|
||||
String s = st.nextToken();
|
||||
|
||||
// If this value is a delimiter /, we have no value for this
|
||||
// part of the resumption token.
|
||||
if (s.equals("/"))
|
||||
{
|
||||
obj[i] = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
obj[i] = s;
|
||||
|
||||
// Skip the delimiter
|
||||
st.nextToken();
|
||||
}
|
||||
|
||||
log.debug("is: " + (String) obj[i]);
|
||||
}
|
||||
|
||||
if (!st.hasMoreTokens())
|
||||
{
|
||||
throw new BadResumptionTokenException();
|
||||
}
|
||||
|
||||
obj[4] = Integer.valueOf(st.nextToken());
|
||||
}
|
||||
catch (NumberFormatException nfe)
|
||||
{
|
||||
// Stack trace loss as OAI Exception does not support cause
|
||||
throw new BadResumptionTokenException();
|
||||
}
|
||||
catch (NoSuchElementException nsee)
|
||||
{
|
||||
// Stack trace loss as OAI Exception does not support cause
|
||||
throw new BadResumptionTokenException();
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.app.oai;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.dspace.content.DCDate;
|
||||
import org.dspace.search.HarvestedItemInfo;
|
||||
|
||||
import ORG.oclc.oai.server.catalog.RecordFactory;
|
||||
import ORG.oclc.oai.server.verb.CannotDisseminateFormatException;
|
||||
|
||||
/**
|
||||
* Implementation of the OAICat RecordFactory base class for DSpace items.
|
||||
*
|
||||
* @author Robert Tansley
|
||||
* @version $Revision$
|
||||
*/
|
||||
public class DSpaceRecordFactory extends RecordFactory
|
||||
{
|
||||
public DSpaceRecordFactory(Properties properties)
|
||||
{
|
||||
// We don't use the OAICat properties; pass on up
|
||||
super(properties);
|
||||
}
|
||||
|
||||
public String fromOAIIdentifier(String identifier)
|
||||
{
|
||||
// Our local identifier is actually the same as the OAI one (the Handle)
|
||||
return identifier;
|
||||
}
|
||||
|
||||
public String quickCreate(Object nativeItem, String schemaURL,
|
||||
String metadataPrefix) throws IllegalArgumentException,
|
||||
CannotDisseminateFormatException
|
||||
{
|
||||
// Not supported
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getOAIIdentifier(Object nativeItem)
|
||||
{
|
||||
String h = DSpaceOAICatalog.OAI_ID_PREFIX
|
||||
+ ((HarvestedItemInfo) nativeItem).handle;
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
public String getDatestamp(Object nativeItem)
|
||||
{
|
||||
Date d = ((HarvestedItemInfo) nativeItem).datestamp;
|
||||
|
||||
// Return as ISO8601
|
||||
return new DCDate(d).toString();
|
||||
}
|
||||
|
||||
public Iterator getSetSpecs(Object nativeItem)
|
||||
{
|
||||
HarvestedItemInfo hii = (HarvestedItemInfo) nativeItem;
|
||||
Iterator<String> i = hii.collectionHandles.iterator();
|
||||
List<String> setSpecs = new LinkedList<String>();
|
||||
|
||||
// Convert the DB Handle string 123.456/789 to the OAI-friendly
|
||||
// hdl_123.456/789
|
||||
while (i.hasNext())
|
||||
{
|
||||
String handle = "hdl_" + i.next();
|
||||
setSpecs.add(handle.replace('/', '_'));
|
||||
}
|
||||
|
||||
return setSpecs.iterator();
|
||||
}
|
||||
|
||||
public boolean isDeleted(Object nativeItem)
|
||||
{
|
||||
HarvestedItemInfo hii = (HarvestedItemInfo) nativeItem;
|
||||
|
||||
return hii.withdrawn;
|
||||
}
|
||||
|
||||
public Iterator getAbouts(Object nativeItem)
|
||||
{
|
||||
// Nothing in the about section for now
|
||||
return new LinkedList().iterator();
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.app.oai;
|
||||
|
||||
import javax.servlet.http.HttpServlet;
|
||||
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
|
||||
/**
|
||||
* Simple servlet to load in DSpace and log4j configurations. Should always be
|
||||
* started up before other servlets (use <loadOnStartup>)
|
||||
*
|
||||
* This class holds code to be removed in the next version of the DSpace XMLUI,
|
||||
* it is now managed by a Shared Context Listener inthe dspace-api project.
|
||||
*
|
||||
* It is deprecated, rather than removed to maintain backward compatibility for
|
||||
* local DSpace 1.5.x customized overlays.
|
||||
*
|
||||
* TODO: Remove in trunk
|
||||
*
|
||||
* @deprecated Use Servlet Context Listener provided in dspace-api (remove in >
|
||||
* 1.5.x)
|
||||
*
|
||||
* @author Robert Tansley
|
||||
* @version $Revision$
|
||||
*/
|
||||
public class LoadDSpaceOAIConfig extends HttpServlet
|
||||
{
|
||||
public void init()
|
||||
{
|
||||
if(!ConfigurationManager.isConfigured())
|
||||
{
|
||||
// Get config parameter
|
||||
String config = getServletContext().getInitParameter("dspace-config");
|
||||
|
||||
// Load in DSpace config
|
||||
ConfigurationManager.loadConfig(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.app.oai;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import ORG.oclc.oai.server.crosswalk.Crosswalk;
|
||||
import ORG.oclc.oai.server.verb.CannotDisseminateFormatException;
|
||||
import org.dspace.content.crosswalk.DisseminationCrosswalk;
|
||||
import org.dspace.core.PluginManager;
|
||||
import org.dspace.search.HarvestedItemInfo;
|
||||
|
||||
import org.jdom.Element;
|
||||
import org.jdom.output.Format;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
|
||||
/**
|
||||
* OAICat crosswalk to allow METS to be harvested.
|
||||
*
|
||||
* No security or privacy measures in place.
|
||||
*
|
||||
* @author Li XiaoYu (Rita)
|
||||
* @author Robert Tansley
|
||||
* @author Tim Donohue (rewrite to use METS DisseminationCrosswalk)
|
||||
*/
|
||||
public class METSCrosswalk extends Crosswalk
|
||||
{
|
||||
private static final Logger log = Logger.getLogger(METSCrosswalk.class);
|
||||
|
||||
// JDOM xml output writer - indented format for readability.
|
||||
private static XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());
|
||||
|
||||
public METSCrosswalk(Properties properties)
|
||||
{
|
||||
super(
|
||||
"http://www.loc.gov/METS/ http://www.loc.gov/standards/mets/mets.xsd");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailableFor(Object nativeItem)
|
||||
{
|
||||
// We have METS for everything
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String createMetadata(Object nativeItem)
|
||||
throws CannotDisseminateFormatException
|
||||
{
|
||||
HarvestedItemInfo hii = (HarvestedItemInfo) nativeItem;
|
||||
|
||||
try
|
||||
{
|
||||
//Get a reference to our DSpace METS DisseminationCrosswalk
|
||||
// (likely this is org.dspace.content.crosswalk.METSDisseminationCrosswalk)
|
||||
DisseminationCrosswalk xwalk = (DisseminationCrosswalk)PluginManager.
|
||||
getNamedPlugin(DisseminationCrosswalk.class, "METS");
|
||||
|
||||
//if no crosswalk found, thrown an error
|
||||
if(xwalk==null)
|
||||
throw new CannotDisseminateFormatException("DSpace cannot disseminate METS format, as no DisseminationCrosswalk is configured which supports 'METS'");
|
||||
|
||||
if(xwalk.canDisseminate(hii.item))
|
||||
{
|
||||
//disseminate the object to METS
|
||||
Element rootElement = xwalk.disseminateElement(hii.item);
|
||||
|
||||
//Return XML results as a formatted String
|
||||
return outputter.outputString(rootElement);
|
||||
}
|
||||
else
|
||||
return null; // cannot disseminate this type of object
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("OAI-PMH METSCrosswalk error", e);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,271 +0,0 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.app.oai;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.dspace.app.util.MetadataExposure;
|
||||
import org.dspace.content.DCValue;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.crosswalk.IConverter;
|
||||
import org.dspace.search.HarvestedItemInfo;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
import org.dspace.core.PluginManager;
|
||||
import org.dspace.core.LogManager;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import ORG.oclc.oai.server.crosswalk.Crosswalk;
|
||||
import ORG.oclc.oai.server.verb.CannotDisseminateFormatException;
|
||||
|
||||
/**
|
||||
* OAI_DC Crosswalk implementation based on oaidc.properties file. All metadata
|
||||
* included in the oaidc.properties file will be mapped on a valid oai_dc
|
||||
* element, invalid oai_dc element will be not used. It is possible specify for
|
||||
* any metadata a converter {@link org.dspace.content.crosswalk.IConverter}
|
||||
* to manipulate the metadata value before that it will be dissemite in OAI_DC.
|
||||
*
|
||||
* @author Robert Tansley
|
||||
* @author Andrea Bollini
|
||||
* @version $Revision$
|
||||
*/
|
||||
public class OAIDCCrosswalk extends Crosswalk
|
||||
{
|
||||
// Pattern containing all the characters we want to filter out / replace
|
||||
// converting a String to xml
|
||||
private static final Pattern invalidXmlPattern = Pattern
|
||||
.compile("([^\\t\\n\\r\\u0020-\\ud7ff\\ue000-\\ufffd\\u10000-\\u10ffff]+|[&<>])");
|
||||
|
||||
// Patter to extract the converter name if any
|
||||
private static final Pattern converterPattern = Pattern.compile(".*\\((.*)\\)");
|
||||
|
||||
private static final String[] oaidcElement = new String[] { "title",
|
||||
"creator", "subject", "description", "publisher", "contributor",
|
||||
"date", "type", "format", "identifier", "source", "language",
|
||||
"relation", "coverage", "rights" };
|
||||
|
||||
/** Location of config file */
|
||||
private static final String configFilePath = ConfigurationManager
|
||||
.getProperty("dspace.dir")
|
||||
+ File.separator
|
||||
+ "config"
|
||||
+ File.separator
|
||||
+ "crosswalks"
|
||||
+ File.separator + "oaidc.properties";
|
||||
|
||||
/** log4j logger */
|
||||
private static Logger log = Logger.getLogger(OAIDCCrosswalk.class);
|
||||
|
||||
private static final Map<String, Set<String>> config = new HashMap<String, Set<String>>();
|
||||
|
||||
static
|
||||
{
|
||||
// Read in configuration
|
||||
Properties crosswalkProps = new Properties();
|
||||
FileInputStream fis = null;
|
||||
try
|
||||
{
|
||||
fis = new FileInputStream(configFilePath);
|
||||
crosswalkProps.load(fis);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new IllegalArgumentException(
|
||||
"Wrong configuration for OAI_DC", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (fis != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
fis.close();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
log.error(ioe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Set<Object> keySet = crosswalkProps.keySet();
|
||||
if (keySet != null)
|
||||
{
|
||||
for (Object key : keySet)
|
||||
{
|
||||
String oaielement = crosswalkProps.getProperty((String) key);
|
||||
if (oaielement != null && !oaielement.trim().equals(""))
|
||||
{
|
||||
Set<String> tmp = config.get(oaielement);
|
||||
if (tmp == null)
|
||||
{
|
||||
tmp = new HashSet<String>();
|
||||
}
|
||||
|
||||
tmp.add((String) key);
|
||||
config.put(oaielement, tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalArgumentException(
|
||||
"Configurazione errata per l'uscita OAI_DC");
|
||||
}
|
||||
}
|
||||
|
||||
public OAIDCCrosswalk(Properties properties)
|
||||
{
|
||||
super("http://www.openarchives.org/OAI/2.0/oai_dc/ "
|
||||
+ "http://www.openarchives.org/OAI/2.0/oai_dc.xsd");
|
||||
}
|
||||
|
||||
public boolean isAvailableFor(Object nativeItem)
|
||||
{
|
||||
// We have DC for everything
|
||||
return true;
|
||||
}
|
||||
|
||||
public String createMetadata(Object nativeItem)
|
||||
throws CannotDisseminateFormatException
|
||||
{
|
||||
Item item = ((HarvestedItemInfo) nativeItem).item;
|
||||
|
||||
StringBuffer metadata = new StringBuffer();
|
||||
|
||||
metadata
|
||||
.append(
|
||||
"<oai_dc:dc xmlns:oai_dc=\"http://www.openarchives.org/OAI/2.0/oai_dc/\" ")
|
||||
.append("xmlns:dc=\"http://purl.org/dc/elements/1.1/\" ")
|
||||
.append(
|
||||
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ")
|
||||
.append(
|
||||
"xsi:schemaLocation=\"http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd\">");
|
||||
|
||||
for (String element : oaidcElement)
|
||||
{
|
||||
Set<String> itemMetadata = config.get(element);
|
||||
|
||||
if (itemMetadata != null && itemMetadata.size() > 0)
|
||||
{
|
||||
for (String mdString : itemMetadata)
|
||||
{
|
||||
String converterName = null;
|
||||
IConverter converter = null;
|
||||
Matcher converterMatcher = converterPattern.matcher(mdString);
|
||||
if (converterMatcher.matches())
|
||||
{
|
||||
converterName = converterMatcher.group(1);
|
||||
converter = (IConverter) PluginManager.getNamedPlugin(
|
||||
IConverter.class, converterName);
|
||||
if (converter == null)
|
||||
{
|
||||
log.warn(LogManager.getHeader(null,
|
||||
"createMetadata",
|
||||
"no converter plugin found with name "
|
||||
+ converterName + " for metadata "
|
||||
+ mdString));
|
||||
}
|
||||
}
|
||||
|
||||
DCValue[] dcValues;
|
||||
if (converterName != null)
|
||||
{
|
||||
dcValues = item.getMetadata(mdString.replaceAll("\\("
|
||||
+ converterName + "\\)", ""));
|
||||
}
|
||||
else
|
||||
{
|
||||
dcValues = item.getMetadata(mdString);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
for (DCValue dcValue : dcValues)
|
||||
{
|
||||
if (!MetadataExposure.isHidden(((HarvestedItemInfo) nativeItem).context,
|
||||
dcValue.schema, dcValue.element, dcValue.qualifier))
|
||||
{
|
||||
String value;
|
||||
if (converter != null)
|
||||
{
|
||||
value = converter.makeConversion(dcValue.value);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = dcValue.value;
|
||||
}
|
||||
|
||||
// Also replace all invalid characters with ' '
|
||||
if (value != null)
|
||||
{
|
||||
StringBuffer valueBuf = new StringBuffer(value
|
||||
.length());
|
||||
Matcher xmlMatcher = invalidXmlPattern
|
||||
.matcher(value.trim());
|
||||
while (xmlMatcher.find())
|
||||
{
|
||||
String group = xmlMatcher.group();
|
||||
|
||||
// group will either contain a character that we
|
||||
// need to encode for xml
|
||||
// (ie. <, > or &), or it will be an invalid
|
||||
// character
|
||||
// test the contents and replace appropriately
|
||||
|
||||
if (group.equals("&"))
|
||||
{
|
||||
xmlMatcher.appendReplacement(valueBuf,
|
||||
"&");
|
||||
}
|
||||
else if (group.equals("<"))
|
||||
{
|
||||
xmlMatcher.appendReplacement(valueBuf,
|
||||
"<");
|
||||
}
|
||||
else if (group.equals(">"))
|
||||
{
|
||||
xmlMatcher.appendReplacement(valueBuf,
|
||||
">");
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlMatcher.appendReplacement(valueBuf, " ");
|
||||
}
|
||||
}
|
||||
|
||||
// add bit of the string after the final match
|
||||
xmlMatcher.appendTail(valueBuf);
|
||||
|
||||
metadata.append("<dc:").append(element).append(">")
|
||||
.append(valueBuf.toString())
|
||||
.append("</dc:").append(element)
|
||||
.append(">");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
// Stack loss as exception does not support cause
|
||||
throw new CannotDisseminateFormatException(e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
metadata.append("</oai_dc:dc>");
|
||||
|
||||
return metadata.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,169 +0,0 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.app.oai;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.crosswalk.DisseminationCrosswalk;
|
||||
import org.dspace.core.PluginManager;
|
||||
import org.dspace.search.HarvestedItemInfo;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
|
||||
import ORG.oclc.oai.server.crosswalk.Crosswalk;
|
||||
import ORG.oclc.oai.server.verb.CannotDisseminateFormatException;
|
||||
|
||||
/**
|
||||
* An OAICat Crosswalk implementation that calls, in turn, on
|
||||
* <code>DisseminationCrosswalk</code> plugins.
|
||||
* It is configured so its "OAI schema label" matches the name of a
|
||||
* <code>DisseminationCrosswalk</code> plugin. This class
|
||||
* will then recognize its name and invoke the correct crosswalk
|
||||
* to produce the results it sends out.
|
||||
* <p>
|
||||
* <b>Configuration:</b>
|
||||
* In the OAICat configuration file (e.g. <code>oaicat.properties</code>
|
||||
* add a line like this for each plugin crosswalk you wish to provide:
|
||||
* <pre>
|
||||
* Crosswalks.<cite>Plugin-Name</cite>=org.dspace.app.oai.PluginCrosswalk
|
||||
*
|
||||
* e.g.
|
||||
*
|
||||
* Crosswalks.DC=org.dspace.app.oai.PluginCrosswalk
|
||||
* </pre>
|
||||
* This creates an OAI metadata prefix "DC" which is implemented
|
||||
* by the dissemination crosswalk plugin that answers to the name "DC".
|
||||
* It, in turn, could be found in the DSpace configuration in a line like:
|
||||
* <pre>
|
||||
* plugin.named.org.dspace.content.crosswalk.DisseminationCrosswalk = \
|
||||
* org.dspace.content.crosswalk.SimpleDCDisseminationCrosswalk = DC
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* Note that all OAI crosswalks are instances of this same class, since
|
||||
* the instance gets bound to a specific <code>DisseminationCrosswalk</code>
|
||||
* when it is created.
|
||||
* <p>
|
||||
* WARNING: This requires at the OAICAT java library version 1.5.38.
|
||||
* It does NOT work with some older versions.
|
||||
*
|
||||
* @author Larry Stone
|
||||
* @version $Revision$
|
||||
*/
|
||||
public class PluginCrosswalk extends Crosswalk
|
||||
{
|
||||
/** log4j category */
|
||||
private static Logger log = Logger.getLogger(PluginCrosswalk.class);
|
||||
|
||||
private DisseminationCrosswalk xwalk = null;
|
||||
|
||||
// preserve the label from config property for diagnostics.
|
||||
private String schemaLabel = null;
|
||||
|
||||
private static XMLOutputter outputUgly = new XMLOutputter();
|
||||
|
||||
/**
|
||||
* Prepare a "schema location" string for the oaicat Crosswalk
|
||||
* class's initialization. This is a string consisting of the
|
||||
* namespace URI, a space, and the schema URL, for the XML
|
||||
* element to be included in the OAI report. This is not documented
|
||||
* in oaicat's manuals so we mention it here.
|
||||
*
|
||||
* Since this gets called by the constructor, we can't initialize the
|
||||
* xwalk field so the plugin gets thrown away.
|
||||
*/
|
||||
private static String makeSchemaLocation(String schemaLabel)
|
||||
{
|
||||
DisseminationCrosswalk xwalk = (DisseminationCrosswalk)
|
||||
PluginManager.getNamedPlugin(DisseminationCrosswalk.class,
|
||||
schemaLabel);
|
||||
if (xwalk != null)
|
||||
{
|
||||
String schemaLoc = xwalk.getSchemaLocation();
|
||||
|
||||
// initialize the oaicat Crosswalk with a "schemalocation" string,
|
||||
// which is "{namespace-URI} {schema-URL}" (space separated)
|
||||
if (schemaLoc != null)
|
||||
{
|
||||
log.debug("Initialized schemaLabel="+schemaLabel+" with schemaLocation = \""+schemaLoc+"\"");
|
||||
return schemaLoc;
|
||||
}
|
||||
log.error("makeSchemaLocation: crosswalk cannot provide schemaLocation, label="+schemaLabel);
|
||||
return "Error No-schemaLocation-for-"+schemaLabel;
|
||||
}
|
||||
log.error("No crosswalk found, makeSchemaLocation giving up, label="+schemaLabel);
|
||||
return "Error No-crosswalk-for-"+schemaLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor; called by
|
||||
* ORG.oclc.oai.server.crosswalk.Crosswalks, which tries first with
|
||||
* args (String schemaLabel, Properties properties). This is
|
||||
* convenient since it lets us use that label to initialize this
|
||||
* instance of the plugin with the DisseminationCrosswalk crosswalk
|
||||
* corresponding to that schemaLabel, instead of creating a subclass
|
||||
* for each one.
|
||||
* <p>
|
||||
* WARNING: This requires at the OAICAT java library version 1.5.37.
|
||||
* It does NOT work with some older versions.
|
||||
*/
|
||||
public PluginCrosswalk(String schemaLabel, Properties properties)
|
||||
{
|
||||
super(makeSchemaLocation(schemaLabel));
|
||||
xwalk = (DisseminationCrosswalk)PluginManager.getNamedPlugin(
|
||||
DisseminationCrosswalk.class, schemaLabel);
|
||||
this.schemaLabel = schemaLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this dissemination is available for the item.
|
||||
*/
|
||||
public boolean isAvailableFor(Object nativeItem)
|
||||
{
|
||||
Item item = ((HarvestedItemInfo) nativeItem).item;
|
||||
return xwalk.canDisseminate(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Do the crosswalk. Returns serialized XML in a string.
|
||||
*/
|
||||
public String createMetadata(Object nativeItem)
|
||||
throws CannotDisseminateFormatException
|
||||
{
|
||||
Item item = ((HarvestedItemInfo) nativeItem).item;
|
||||
try
|
||||
{
|
||||
log.debug("OAI plugin, schema="+schemaLabel+", preferList="+String.valueOf(xwalk.preferList()));
|
||||
if (xwalk.preferList())
|
||||
{
|
||||
return outputUgly.outputString(xwalk.disseminateList(item));
|
||||
}
|
||||
else
|
||||
{
|
||||
return outputUgly.outputString(xwalk.disseminateElement(item));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error(this.getClass().getName()+
|
||||
": hiding exception in CannotDisseminateFormatException:"+
|
||||
e.toString());
|
||||
|
||||
StringWriter sw = new StringWriter();
|
||||
e.printStackTrace(new PrintWriter(sw));
|
||||
log.error("*** Stack trace follows:");
|
||||
log.error(sw.toString());
|
||||
|
||||
// Stack loss as exception does not support cause
|
||||
throw new CannotDisseminateFormatException(schemaLabel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,245 +0,0 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.app.oai;
|
||||
|
||||
import java.util.Properties;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.dspace.app.util.Util;
|
||||
import org.dspace.content.DCValue;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.Bitstream;
|
||||
import org.dspace.content.Bundle;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.Community;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
import org.dspace.search.HarvestedItemInfo;
|
||||
|
||||
import ORG.oclc.oai.server.crosswalk.Crosswalk;
|
||||
import ORG.oclc.oai.server.verb.CannotDisseminateFormatException;
|
||||
|
||||
/**
|
||||
* An OAICat Crosswalk implementation that extracts
|
||||
* DSpace items into typed RDF format.
|
||||
*
|
||||
* @author Richard Rodgers
|
||||
* @version $Revision$
|
||||
*/
|
||||
public class RDFCrosswalk extends Crosswalk
|
||||
{
|
||||
// base URL for thumbnails
|
||||
private String baseUrl = null;
|
||||
// hostname for rdf URI
|
||||
private String hostName = null;
|
||||
|
||||
public RDFCrosswalk(Properties properties)
|
||||
{
|
||||
super(
|
||||
"http://www.openarchives.org/OAI/2.0/rdf/ http://www.openarchives.org/OAI/2.0/rdf.xsd");
|
||||
baseUrl = ConfigurationManager.getProperty("dspace.url");
|
||||
hostName = ConfigurationManager.getProperty("dspace.hostname");
|
||||
}
|
||||
|
||||
public boolean isAvailableFor(Object nativeItem)
|
||||
{
|
||||
// Only implemented for items so far
|
||||
return (nativeItem instanceof HarvestedItemInfo);
|
||||
}
|
||||
|
||||
public String createMetadata(Object nativeItem)
|
||||
throws CannotDisseminateFormatException
|
||||
{
|
||||
HarvestedItemInfo itemInfo = (HarvestedItemInfo)nativeItem;
|
||||
Item item = itemInfo.item;
|
||||
|
||||
// Get all the DC
|
||||
DCValue[] allDC = item.getDC(Item.ANY, Item.ANY, Item.ANY);
|
||||
|
||||
StringBuffer metadata = new StringBuffer();
|
||||
|
||||
/*
|
||||
metadata
|
||||
.append(
|
||||
"<oai_dc:dc xmlns:oai_dc=\"http://www.openarchives.org/OAI/2.0/oai_dc/\" ")
|
||||
.append("xmlns:dc=\"http://purl.org/dc/elements/1.1/\" ")
|
||||
.append(
|
||||
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ")
|
||||
.append(
|
||||
"xsi:schemaLocation=\"http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd\">");
|
||||
*/
|
||||
|
||||
metadata
|
||||
.append(
|
||||
"<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" " )
|
||||
.append("xmlns:ow=\"http://www.ontoweb.org/ontology/1#\" " )
|
||||
.append("xmlns:dc=\"http://purl.org/dc/elements/1.1/\" " )
|
||||
.append("xmlns:ds=\"http://dspace.org/ds/elements/1.1/\" " )
|
||||
.append(
|
||||
"xsi:schemaLocation=\"http://www.w3.org/1999/02/22-rdf-syntax-ns# http://www.openarchives.org/OAI/2.0/rdf.xsd\">");
|
||||
|
||||
|
||||
// construct URI for item
|
||||
metadata.append("<ow:Publication rdf:about=\"oai:")
|
||||
.append(hostName)
|
||||
.append(":")
|
||||
.append(item.getHandle())
|
||||
.append("\">");
|
||||
|
||||
for (int i = 0; i < allDC.length; i++)
|
||||
{
|
||||
if (screened(allDC[i]))
|
||||
{
|
||||
String element = allDC[i].element;
|
||||
|
||||
// contributor.author exposed as 'creator'
|
||||
if (allDC[i].element.equals("contributor")
|
||||
&& (allDC[i].qualifier != null)
|
||||
&& allDC[i].qualifier.equals("author"))
|
||||
{
|
||||
element = "creator";
|
||||
}
|
||||
|
||||
// Escape XML chars <, > and &
|
||||
String value = allDC[i].value;
|
||||
|
||||
// Check for null values
|
||||
if (value == null)
|
||||
{
|
||||
value = "";
|
||||
}
|
||||
|
||||
// First do &'s - need to be careful not to replace the
|
||||
// & in "&" again!
|
||||
int c = -1;
|
||||
|
||||
while ((c = value.indexOf("&", c + 1)) > -1)
|
||||
{
|
||||
value = value.substring(0, c) + "&"
|
||||
+ value.substring(c + 1);
|
||||
}
|
||||
|
||||
while ((c = value.indexOf("<")) > -1)
|
||||
{
|
||||
value = value.substring(0, c) + "<"
|
||||
+ value.substring(c + 1);
|
||||
}
|
||||
|
||||
while ((c = value.indexOf(">")) > -1)
|
||||
{
|
||||
value = value.substring(0, c) + ">"
|
||||
+ value.substring(c + 1);
|
||||
}
|
||||
|
||||
metadata.append("<dc:").append(element).append(">")
|
||||
.append(value)
|
||||
.append("</dc:").append(element).append(">");
|
||||
}
|
||||
}
|
||||
|
||||
// add extended info - collection, communities, and thumbnail URLs
|
||||
Collection[] colls = null;
|
||||
Community[] comms = null;
|
||||
Bundle[] origBundles = null;
|
||||
Bundle[] thumbBundles = null;
|
||||
try
|
||||
{
|
||||
colls = item.getCollections();
|
||||
comms = item.getCommunities();
|
||||
origBundles = item.getBundles("ORIGINAL");
|
||||
thumbBundles = item.getBundles("THUMBNAIL");
|
||||
}
|
||||
catch(SQLException sqlE)
|
||||
{
|
||||
}
|
||||
|
||||
// all parent communities map to DC source
|
||||
for (int i = 0; i < comms.length; i++)
|
||||
{
|
||||
metadata.append("<dc:source>")
|
||||
.append(comms[i].getMetadata("name"))
|
||||
.append("</dc:source>");
|
||||
}
|
||||
// as do collections
|
||||
for (int j = 0; j < colls.length; j++)
|
||||
{
|
||||
metadata.append("<dc:source>")
|
||||
.append(colls[j].getMetadata("name"))
|
||||
.append("</dc:source>");
|
||||
}
|
||||
|
||||
if (origBundles.length > 0)
|
||||
{
|
||||
Bitstream[] bitstreams = origBundles[0].getBitstreams();
|
||||
// add a URL for each original that has a thumbnail
|
||||
for (int j = 0; j < bitstreams.length; j++)
|
||||
{
|
||||
String tName = bitstreams[j].getName() + ".jpg";
|
||||
Bitstream tb = null;
|
||||
|
||||
if (thumbBundles.length > 0)
|
||||
{
|
||||
tb = thumbBundles[0].getBitstreamByName(tName);
|
||||
}
|
||||
|
||||
if (tb != null)
|
||||
{
|
||||
String thumbUrl = null;
|
||||
try
|
||||
{
|
||||
thumbUrl = baseUrl + "/retrieve/" + tb.getID() + "/" +
|
||||
Util.encodeBitstreamName(tb.getName(),
|
||||
Constants.DEFAULT_ENCODING);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
}
|
||||
metadata.append("<dc:coverage>")
|
||||
.append(thumbUrl)
|
||||
.append("</dc:coverage>");
|
||||
}
|
||||
}
|
||||
}
|
||||
//metadata.append("</oai_ds:ds>");
|
||||
metadata.append("</ow:Publication>");
|
||||
metadata.append("</rdf:RDF>");
|
||||
|
||||
return metadata.toString();
|
||||
}
|
||||
|
||||
/*
|
||||
* Exclude Item DC elements unsuitable for harvest
|
||||
*/
|
||||
private boolean screened(DCValue dcValue)
|
||||
{
|
||||
// description.providence
|
||||
if (isQualified(dcValue, "description", "provenance"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// format.extent
|
||||
if (isQualified(dcValue, "format", "extent"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// date.available is algorithmically identical to date.accessioned
|
||||
// suppress one
|
||||
if (isQualified(dcValue, "date", "accessioned"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isQualified(DCValue dcValue, String elName, String qualName)
|
||||
{
|
||||
return (dcValue.element.equals(elName) &&
|
||||
dcValue.qualifier != null &&
|
||||
dcValue.qualifier.equals(qualName));
|
||||
}
|
||||
}
|
||||
@@ -1,701 +0,0 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.app.oai;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.Properties;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
import org.dspace.core.Utils;
|
||||
import org.dspace.search.HarvestedItemInfo;
|
||||
import org.dspace.content.*;
|
||||
|
||||
import ORG.oclc.oai.server.crosswalk.Crosswalk;
|
||||
import ORG.oclc.oai.server.verb.CannotDisseminateFormatException;
|
||||
|
||||
/**
|
||||
* A Crosswalk implementation that extracts qualified Dublin Core from
|
||||
* DSpace items into the uketd_dc format.
|
||||
*
|
||||
* It supports the writing of UKETD_DC metadata
|
||||
* in a METS document and to make the schema URIs available for
|
||||
* inclusion in such a METS document. For this reason, the writing
|
||||
* of the metadata itself has been separated from the writing
|
||||
* of the schemas.
|
||||
* This version places the writing of the header and metadata
|
||||
* in its own method called by createMetadata so the headers are
|
||||
* included in the UKETD_METS that also uses those methods.
|
||||
* This allows the writeMetadata method to remain unchanged,
|
||||
* with no header information included. It is therefore consistent with
|
||||
* other DSpace crosswalks.
|
||||
*
|
||||
* @author Paul Needham (Cranfield University)
|
||||
* @author Jon Bell & Stuart Lewis (Aberystwyth University)
|
||||
*/
|
||||
public class UKETDDCCrosswalk extends Crosswalk
|
||||
{
|
||||
// Pattern containing all the characters we want to filter out / replace
|
||||
// converting a String to xml
|
||||
private static final Pattern invalidXmlPattern =
|
||||
Pattern.compile("([^\\t\\n\\r\\u0020-\\ud7ff\\ue000-\\ufffd\\u10000-\\u10ffff]+|[&<>])");
|
||||
|
||||
// String constants for metadata schemas...
|
||||
|
||||
/** Used to open the metadata in a OAI-PMH record. */
|
||||
private String uketdIn = "<uketd_dc:uketddc";
|
||||
|
||||
/** The identifier for the uketd namespace. */
|
||||
private String uketdNs = "uketd_dc";
|
||||
|
||||
/** The URI of the uketd namespace. */
|
||||
private String uketdUri = "http://naca.central.cranfield.ac.uk/ethos-oai/2.0/";
|
||||
|
||||
/** The identifier for the namespace of the DC used in the UKETD_DC metadata set. */
|
||||
private String dcNs = "dc";
|
||||
|
||||
/** The URI of the DC namespace. */
|
||||
private String dcUri = "http://purl.org/dc/elements/1.1/";
|
||||
|
||||
/** The identifier for the namespace of the qualified DC terms used in UKETD_DC. */
|
||||
private String dcTermsNs = "dcterms";
|
||||
|
||||
/** The URI of the DC terms namespace. */
|
||||
private String dcTermsUri = "http://purl.org/dc/terms/";
|
||||
|
||||
/** Identifier of the UKETD terms namespace.*/
|
||||
private String uketdTermsNs = "uketdterms";
|
||||
|
||||
/** The URI of the uketd terms namespace. */
|
||||
private String uketdTermsUri = "http://naca.central.cranfield.ac.uk/ethos-oai/terms/";
|
||||
|
||||
/** The xsi string (identifier and URI) used for UKETD records.*/
|
||||
private String xsi = "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"";
|
||||
|
||||
/** The xsi schema location tag, used in UKETD records. */
|
||||
private String schemaLoc = "xsi:schemaLocation";
|
||||
|
||||
/** The URI of the uketd location namespace. */
|
||||
private static String uketdSchemaLocNs = "http://naca.central.cranfield.ac.uk/ethos-oai/2.0/";
|
||||
|
||||
/** The URI of the uketd location. */
|
||||
private static String uketdSchemaLocUri = "http://naca.central.cranfield.ac.uk/ethos-oai/2.0/uketd_dc.xsd";
|
||||
|
||||
|
||||
/**
|
||||
* UKETDDCCrosswalk contructor.
|
||||
*
|
||||
* @param properties Not used
|
||||
* */
|
||||
public UKETDDCCrosswalk(Properties properties)
|
||||
{
|
||||
super(uketdSchemaLocNs + " " + uketdSchemaLocUri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the identifier for the UKETD namespace.
|
||||
*
|
||||
* @return uketdNs
|
||||
*/
|
||||
public String getUketdNs ()
|
||||
{
|
||||
return uketdNs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URI of the UKETD namespace.
|
||||
*
|
||||
* @return uketdUri
|
||||
*/
|
||||
public String getUketdUri ()
|
||||
{
|
||||
return uketdUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the identifier for the Dublin Core namespace.
|
||||
*
|
||||
* @return dcNs
|
||||
*/
|
||||
public String getDcNs ()
|
||||
{
|
||||
return dcNs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URI of the Dublin Core namespace.
|
||||
*
|
||||
* @return dcUri
|
||||
*/
|
||||
public String getDcUri ()
|
||||
{
|
||||
return dcUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the identifier for the DC terms (qualifiers) namespace.
|
||||
*
|
||||
* @return cdTermsNs
|
||||
*/
|
||||
public String getDcTermsNs ()
|
||||
{
|
||||
return dcTermsNs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URI of the DC terms namespace.
|
||||
*
|
||||
* @return dcTermsUri
|
||||
*/
|
||||
public String getDcTermsUri ()
|
||||
{
|
||||
return dcTermsUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the identifier for the UKETD terms namespace.
|
||||
*
|
||||
* @return uketdTermsNs
|
||||
*/
|
||||
public String getUketdTermsNs ()
|
||||
{
|
||||
return uketdTermsNs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URI of the UKETD terms namespace.
|
||||
*
|
||||
* @return uketdTermsUri
|
||||
*/
|
||||
public String getUketdTermsUri ()
|
||||
{
|
||||
return uketdTermsUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the identifier for the UKETD schema location.
|
||||
*
|
||||
* @return uketdSchemaLocNs
|
||||
*/
|
||||
public String getUketdSchemaLocNs ()
|
||||
{
|
||||
return uketdSchemaLocNs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URI of the UKETD schema location.
|
||||
*
|
||||
* @return uketdSchemaLocUri
|
||||
*/
|
||||
public String getUketdSchemaLocUri ()
|
||||
{
|
||||
return uketdSchemaLocUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows what items UKETD_DC OAI-PMH is available for.
|
||||
* This is every item in the repository.
|
||||
*
|
||||
* @return a boolean (true)
|
||||
*/
|
||||
public boolean isAvailableFor(Object nativeItem)
|
||||
{
|
||||
// We have DC for everything
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the metadata necessary for UKTEDDC crosswalk.
|
||||
* Adds the name space details and schemas to the metadata itself.
|
||||
* It therefore creates a complete OAI-PMH record that matches
|
||||
* the UKETD_DC metadata prefix.
|
||||
*
|
||||
* @return The OAI-PMH xml
|
||||
*/
|
||||
public String createMetadata (Object nativeItem)
|
||||
throws CannotDisseminateFormatException
|
||||
{
|
||||
// Get the Item
|
||||
Item item = ((HarvestedItemInfo) nativeItem).item;
|
||||
|
||||
// Write the record out
|
||||
return writeMetadataWithSchema(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the item's metadata, headed by the schema namespace
|
||||
* details. Separated from createMetadata, so UKETD_METS can
|
||||
* use the method with an Item , not an Object (nativeItem).
|
||||
*
|
||||
* @param item The org.dspace.content.Item
|
||||
* @return a String, the item's metadata in UKETD_DC format.
|
||||
* @throws SQLException
|
||||
*/
|
||||
public String writeMetadataWithSchema (Item item)
|
||||
{
|
||||
StringBuffer metadata = new StringBuffer ();
|
||||
metadata.append(uketdIn).append(" ");
|
||||
metadata.append ("xmlns:" + uketdNs + "=\"" + uketdUri + "\" ");
|
||||
metadata.append ("xmlns:" + dcNs + "=\"" + dcUri + "\" ");
|
||||
metadata.append ("xmlns:" + dcTermsNs + "=\"" + dcTermsUri + "\" ");
|
||||
metadata.append ("xmlns:" + uketdTermsNs + "=\"" + uketdTermsUri + "\" ");
|
||||
metadata.append(xsi).append(" ");
|
||||
metadata.append (schemaLoc + "=\"" + uketdSchemaLocNs + " ");
|
||||
metadata.append(uketdSchemaLocUri).append("\">\n");
|
||||
metadata.append (writeMetadata (item));
|
||||
metadata.append ("</uketd_dc:uketddc>\n");
|
||||
return metadata.toString ( );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Writes the UKETD_DC metadata for the specified item.
|
||||
* It simply gets hold of the Dublin Core for an Item
|
||||
* and converts it to UKEDT_DC, including the splitting
|
||||
* of the Dublin Core publisher and type fields.
|
||||
* The metadata is identical to that returned by
|
||||
* the original version's create metadata method,
|
||||
* without the schema information.
|
||||
* This method does no checking of the correctness of the
|
||||
* metadata format, nor does it throw any exception.
|
||||
*
|
||||
* @param item a org.dspace.content.Item
|
||||
* @return a String, the item's metadata in UKETD_DC xml.
|
||||
*/
|
||||
public String writeMetadata(Item item)
|
||||
{
|
||||
// The string we are constructing
|
||||
StringBuffer metadata = new StringBuffer();
|
||||
|
||||
// Get all the DC
|
||||
DCValue[] allDC = item.getMetadata(MetadataSchema.DC_SCHEMA, Item.ANY, Item.ANY, Item.ANY);
|
||||
|
||||
// Get the handle of the item
|
||||
String itemhandle = item.getHandle();
|
||||
|
||||
for (int i = 0; i < allDC.length; i++)
|
||||
{
|
||||
// Get the element, qualifier and value
|
||||
String element = allDC[i].element;
|
||||
String qualifier = allDC[i].qualifier;
|
||||
String value = Utils.addEntities(allDC[i].value);
|
||||
|
||||
// title
|
||||
if (allDC[i].element.equals("title"))
|
||||
{
|
||||
if (allDC[i].qualifier != null) {
|
||||
if (allDC[i].qualifier.equals("alternative"))
|
||||
{
|
||||
// title.alternative exposed as 'dcterms:alternative'
|
||||
this.makeDCTermsElement(qualifier, null, value, metadata);
|
||||
}
|
||||
} else
|
||||
{
|
||||
this.makeDCElement(element, null, value, metadata);
|
||||
}
|
||||
}
|
||||
|
||||
// contributor
|
||||
if (allDC[i].element.equals("contributor"))
|
||||
{
|
||||
if (allDC[i].qualifier != null) {
|
||||
if (allDC[i].qualifier.equals("author"))
|
||||
{
|
||||
this.makeDCElement("creator", null, value, metadata);
|
||||
} else if ((allDC[i].qualifier.equals("advisor")) ||
|
||||
(allDC[i].qualifier.equals("sponsor")))
|
||||
{
|
||||
// contributor.qualifier exposed as 'uketdterms:qualifier'
|
||||
this.makeUKDCTermsElement(qualifier, null, value, metadata);
|
||||
} else if (allDC[i].qualifier.equals("funder"))
|
||||
{
|
||||
// contributor.qualifier exposed as 'uketdterms:qualifier'
|
||||
this.makeUKDCTermsElement("sponsor", null, value, metadata);
|
||||
} else
|
||||
{
|
||||
// contributor.qualifier exposed as 'dcterms:qualifier'
|
||||
this.makeDCTermsElement(qualifier, null, value, metadata);
|
||||
}
|
||||
} else {
|
||||
this.makeDCElement(element, null, value, metadata);
|
||||
}
|
||||
}
|
||||
|
||||
// subject
|
||||
if (allDC[i].element.equals("subject"))
|
||||
{
|
||||
if (allDC[i].qualifier != null) {
|
||||
boolean ddc = allDC[i].qualifier.equals("ddc");
|
||||
boolean lcc = allDC[i].qualifier.equals("lcc");
|
||||
boolean lcsh = allDC[i].qualifier.equals("lcsh");
|
||||
boolean mesh = allDC[i].qualifier.equals("mesh");
|
||||
boolean udc = allDC[i].qualifier.equals("udc");
|
||||
if (ddc || lcc || lcsh || mesh || udc)
|
||||
{
|
||||
// subject.qualifier exposed as 'dc:element xsi:type="dcterms:qualifier"'
|
||||
qualifier = qualifier.toUpperCase();
|
||||
this.makeDCElement(element, qualifier, value, metadata);
|
||||
} else
|
||||
{
|
||||
this.makeDCElement(element, null, value, metadata);
|
||||
}
|
||||
} else
|
||||
{
|
||||
this.makeDCElement(element, null, value, metadata);
|
||||
}
|
||||
}
|
||||
|
||||
// description
|
||||
if (allDC[i].element.equals("description"))
|
||||
{
|
||||
if (allDC[i].qualifier != null)
|
||||
{
|
||||
if (allDC[i].qualifier.equals("abstract"))
|
||||
{
|
||||
// e.g. description.abstract exposed as 'dcterms:abstract'
|
||||
this.makeDCTermsElement(qualifier, null, value, metadata);
|
||||
} else if (allDC[i].qualifier.equals("sponsorship"))
|
||||
{
|
||||
// description.sponsorship exposed as 'uketdterms:sponsor"'
|
||||
this.makeUKDCTermsElement("sponsor", null, value, metadata);
|
||||
}
|
||||
} else {
|
||||
this.makeDCElement(element, null, value, metadata);
|
||||
}
|
||||
}
|
||||
|
||||
// publisher
|
||||
if (allDC[i].element.equals("publisher"))
|
||||
{
|
||||
if (allDC[i].qualifier != null) {
|
||||
if ((allDC[i].qualifier.equals("department")) ||
|
||||
(allDC[i].qualifier.equals("commercial")))
|
||||
{
|
||||
this.makeUKDCTermsElement(qualifier, null, value, metadata);
|
||||
}
|
||||
} else {
|
||||
String[] pubParts = value.split("(?<!(&[0-9a-zA-Z#]{2,4}));");
|
||||
this.makeUKDCTermsElement("institution", null,
|
||||
pubParts[0], metadata);
|
||||
StringBuffer dept = new StringBuffer();
|
||||
if ((pubParts.length > 1) && (pubParts[1] != null)) {
|
||||
dept.append(pubParts[1] + ";");
|
||||
}
|
||||
if ((pubParts.length > 2) && (pubParts[2] != null)) {
|
||||
dept.append(" " + pubParts[2]);
|
||||
}
|
||||
if (dept.length() > 0) {
|
||||
this.makeUKDCTermsElement("department", null,
|
||||
dept.toString(), metadata);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// date
|
||||
if (allDC[i].element.equals("date"))
|
||||
{
|
||||
if (allDC[i].qualifier != null)
|
||||
{
|
||||
if (allDC[i].qualifier.equals("issued"))
|
||||
{
|
||||
this.makeDCTermsElement(qualifier, null, value, metadata);
|
||||
} else
|
||||
{
|
||||
this.makeDCElement(element, null, value, metadata);
|
||||
}
|
||||
} else
|
||||
{
|
||||
this.makeDCElement(element, null, value, metadata);
|
||||
}
|
||||
}
|
||||
|
||||
// type
|
||||
if (allDC[i].element.equals("type"))
|
||||
{
|
||||
if (allDC[i].qualifier != null)
|
||||
{
|
||||
if ((allDC[i].qualifier.equals("qualificationlevel")) ||
|
||||
(allDC[i].qualifier.equals("qualificationname")))
|
||||
{
|
||||
this.makeUKDCTermsElement(qualifier, null, value, metadata);
|
||||
}
|
||||
} else {
|
||||
String[] Typepart = value.split("[;]");
|
||||
this.makeDCElement(element, null, Typepart[0], metadata);
|
||||
if ((Typepart.length > 1) && (Typepart[1] != null))
|
||||
{
|
||||
this.makeUKDCTermsElement("qualificationlevel", null,
|
||||
Typepart[1], metadata);
|
||||
} if ((Typepart.length > 2) && (Typepart[2] != null))
|
||||
{
|
||||
this.makeUKDCTermsElement("qualificationname", null,
|
||||
Typepart[2], metadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// language
|
||||
if (allDC[i].element.equals("language"))
|
||||
{
|
||||
if (allDC[i].qualifier != null) {
|
||||
if (allDC[i].qualifier.equals("iso"))
|
||||
{
|
||||
// language.iso exposed as 'dc:element xsi:type="dcterms:qualifier"'
|
||||
this.makeDCElement(element, "ISO639-2", value, metadata);
|
||||
} else
|
||||
{
|
||||
this.makeDCElement(element, null, value, metadata);
|
||||
}
|
||||
} else
|
||||
{
|
||||
this.makeDCElement(element, null, value, metadata);
|
||||
}
|
||||
}
|
||||
|
||||
// relation
|
||||
if (allDC[i].element.equals("relation"))
|
||||
{
|
||||
if (allDC[i].qualifier != null) {
|
||||
if (allDC[i].qualifier.equals("hasversion"))
|
||||
{
|
||||
// relation.hasversion exposed as 'dcterms:qualifier'
|
||||
this.makeDCElement("hasVersion", null, value, metadata);
|
||||
} else if ((allDC[i].qualifier.equals("references")) ||
|
||||
(allDC[i].qualifier.equals("requires")))
|
||||
{
|
||||
// relation.references exposed as 'dcterms:qualifier'
|
||||
this.makeDCTermsElement(qualifier, null, value, metadata);
|
||||
} else
|
||||
{
|
||||
this.makeDCElement(element, null, value, metadata);
|
||||
}
|
||||
} else
|
||||
{
|
||||
this.makeDCElement(element, null, value, metadata);
|
||||
}
|
||||
}
|
||||
|
||||
// format
|
||||
if (allDC[i].element.equals("format"))
|
||||
{
|
||||
if (allDC[i].qualifier != null)
|
||||
{
|
||||
if (allDC[i].qualifier.equals("extent"))
|
||||
{
|
||||
// format exposed as 'dcterms:qualifier'
|
||||
this.makeDCTermsElement(qualifier, null, value, metadata);
|
||||
} else if (allDC[i].qualifier.equals("mimetype"))
|
||||
{
|
||||
this.makeDCElement(element, "IMT", value, metadata);
|
||||
}
|
||||
} else
|
||||
{
|
||||
// format exposed as 'dc:element'
|
||||
this.makeDCElement(element, null, value, metadata);
|
||||
}
|
||||
}
|
||||
|
||||
// identifier
|
||||
if (allDC[i].element.equals("identifier"))
|
||||
{
|
||||
if (allDC[i].qualifier != null)
|
||||
{
|
||||
if (allDC[i].qualifier.equals("uri"))
|
||||
{
|
||||
this.makeDCTermsElement("isReferencedBy", "URI", value, metadata);
|
||||
} else if (allDC[i].qualifier.equals("citation"))
|
||||
{
|
||||
this.makeDCTermsElement("hasVersion", null, value, metadata);
|
||||
} else if (allDC[i].qualifier.equals("grantnumber"))
|
||||
{
|
||||
this.makeUKDCTermsElement(qualifier, null, value, metadata);
|
||||
}
|
||||
} else
|
||||
{
|
||||
// identifier exposed as 'dc:element'
|
||||
this.makeDCElement(element, null, value, metadata);
|
||||
}
|
||||
}
|
||||
|
||||
// rights
|
||||
if (allDC[i].element.equals("rights"))
|
||||
{
|
||||
if (allDC[i].qualifier != null)
|
||||
{
|
||||
if ((allDC[i].qualifier.equals("embargodate")) ||
|
||||
(allDC[i].qualifier.equals("embargoreason")))
|
||||
{
|
||||
this.makeUKDCTermsElement(qualifier, null, value, metadata);
|
||||
} else
|
||||
{
|
||||
// rights exposed as 'dc:element'
|
||||
this.makeDCElement(element, null, value, metadata);
|
||||
}
|
||||
} else
|
||||
{
|
||||
// rights exposed as 'dc:element'
|
||||
this.makeDCElement(element, null, value, metadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generate bitstream URIs
|
||||
Bundle[] bundles = {};
|
||||
try
|
||||
{
|
||||
bundles = item.getBundles("ORIGINAL");
|
||||
String url;
|
||||
if (bundles.length > 0)
|
||||
{
|
||||
// Itterate through each bundle
|
||||
for (int i = 0; i < bundles.length; i++)
|
||||
{
|
||||
// Itterate through each bitstream
|
||||
Bitstream[] bitstreams = bundles[i].getBitstreams();
|
||||
for (int k = 0; k < bitstreams.length ; k++)
|
||||
{
|
||||
// Skip internal types
|
||||
if (!bitstreams[k].getFormat().isInternal())
|
||||
{
|
||||
url = ConfigurationManager.getProperty("dspace.url") +
|
||||
"/bitstream/" + itemhandle + "/" +
|
||||
bitstreams[k].getSequenceID() + "/" +
|
||||
bitstreams[k].getName();
|
||||
this.makeDCElement("identifier", "URI", url, metadata);
|
||||
this.makeUKDCTermsElement("checksum",
|
||||
bitstreams[k].getChecksumAlgorithm(),
|
||||
bitstreams[k].getChecksum(), metadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (SQLException sqle)
|
||||
{
|
||||
// Nothing we can do
|
||||
}
|
||||
|
||||
// Return the metadata - all done!
|
||||
return metadata.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Private wrapper method to create a DC term element.
|
||||
*
|
||||
* @param element The element name
|
||||
* @param qualifier The qualifier name (or null)
|
||||
* @param value The value of the element
|
||||
* @param buffer The buffer to add the element to
|
||||
* @return The buffer with the new element appended to
|
||||
*/
|
||||
private StringBuffer makeDCElement(String element, String qualifier,
|
||||
String value, StringBuffer buffer)
|
||||
{
|
||||
return this.makeTermsElement(element, qualifier, value,
|
||||
buffer, "dc", "dcterms");
|
||||
}
|
||||
|
||||
/**
|
||||
* Private wrapper method to create a DCterms term element.
|
||||
*
|
||||
* @param element The element name
|
||||
* @param qualifier The qualifier name (or null)
|
||||
* @param value The value of the element
|
||||
* @param buffer The buffer to add the element to
|
||||
* @return The buffer with the new element appended to
|
||||
*/
|
||||
private StringBuffer makeDCTermsElement(String element, String qualifier,
|
||||
String value, StringBuffer buffer)
|
||||
{
|
||||
return this.makeTermsElement(element, qualifier, value,
|
||||
buffer, "dcterms", "dcterms");
|
||||
}
|
||||
|
||||
/**
|
||||
* Private wrapper method to create a UKETD DC term element.
|
||||
*
|
||||
* @param element The element name
|
||||
* @param qualifier The qualifier name (or null)
|
||||
* @param value The value of the element
|
||||
* @param buffer The buffer to add the element to
|
||||
* @return The buffer with the new element appended to
|
||||
*/
|
||||
private StringBuffer makeUKDCTermsElement(String element, String qualifier,
|
||||
String value, StringBuffer buffer)
|
||||
{
|
||||
return this.makeTermsElement(element, qualifier, value,
|
||||
buffer, "uketdterms", "uketdterms");
|
||||
}
|
||||
|
||||
/**
|
||||
* Private wrapper method to create an element.
|
||||
*
|
||||
* @param element The element name
|
||||
* @param qualifier The qualifier name (or null)
|
||||
* @param value The value of the element
|
||||
* @param buffer The buffer to add the element to
|
||||
* @param terms The namespace of the term
|
||||
* @return The buffer with the new element appended to
|
||||
*/
|
||||
|
||||
private StringBuffer makeTermsElement(String element, String qualifier,
|
||||
String value, StringBuffer buffer,
|
||||
String namespace, String terms)
|
||||
{
|
||||
// Escape XML chars <, > and &
|
||||
// Also replace all invalid characters with ' '
|
||||
if (value != null)
|
||||
{
|
||||
StringBuffer valueBuf = new StringBuffer(value.length());
|
||||
Matcher xmlMatcher = invalidXmlPattern.matcher(value.trim());
|
||||
while (xmlMatcher.find())
|
||||
{
|
||||
String group = xmlMatcher.group();
|
||||
|
||||
// group will either contain a character that we need to encode for xml
|
||||
// (ie. <, > or &), or it will be an invalid character
|
||||
// test the contents and replace appropriately
|
||||
if ("&".equals(group))
|
||||
{
|
||||
xmlMatcher.appendReplacement(valueBuf, "&");
|
||||
}
|
||||
else if ("<".equals(group))
|
||||
{
|
||||
xmlMatcher.appendReplacement(valueBuf, "<");
|
||||
}
|
||||
else if (">".equals(group))
|
||||
{
|
||||
xmlMatcher.appendReplacement(valueBuf, ">");
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlMatcher.appendReplacement(valueBuf, " ");
|
||||
}
|
||||
}
|
||||
|
||||
// add bit of the string after the final match
|
||||
xmlMatcher.appendTail(valueBuf);
|
||||
|
||||
if (qualifier == null)
|
||||
{
|
||||
buffer.append("<").append(namespace).append(":").append(element).append(">").append(valueBuf.toString()).append("</").append(namespace).append(":").append(element).append(">\n");
|
||||
} else
|
||||
{
|
||||
buffer.append("<").append(namespace).append(":").append(element).append(" xsi:type=\"").append(terms).append(":").append(qualifier).append("\">").append(valueBuf.toString()).append("</").append(namespace).append(":").append(element).append(">\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer.append("<").append(namespace).append(":").append(element).append(" />\n");
|
||||
}
|
||||
|
||||
// Return the updated buffer
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.xoai;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.log4j.LogManager;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.solr.client.solrj.SolrServerException;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.xoai.data.DSpaceIdentify;
|
||||
import org.dspace.xoai.data.DSpaceItemDatabaseRepository;
|
||||
import org.dspace.xoai.data.DSpaceItemRepository;
|
||||
import org.dspace.xoai.data.DSpaceItemSolrRepository;
|
||||
import org.dspace.xoai.data.DSpaceSetRepository;
|
||||
import org.dspace.xoai.filter.DSpaceFilter;
|
||||
import org.dspace.xoai.solr.DSpaceSolrServer;
|
||||
import org.dspace.xoai.util.XOAICacheManager;
|
||||
|
||||
import com.lyncode.xoai.dataprovider.OAIDataProvider;
|
||||
import com.lyncode.xoai.dataprovider.OAIRequestParameters;
|
||||
import com.lyncode.xoai.dataprovider.core.XOAIManager;
|
||||
import com.lyncode.xoai.dataprovider.exceptions.InvalidContextException;
|
||||
import com.lyncode.xoai.dataprovider.filter.AbstractFilter;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class DSpaceOAIDataProvider extends HttpServlet
|
||||
{
|
||||
private static Logger log = LogManager
|
||||
.getLogger(DSpaceOAIDataProvider.class);
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
try
|
||||
{
|
||||
XOAIManager.initialize(ConfigurationManager
|
||||
.getProperty("oai", "config.dir"));
|
||||
if (!"database".equals(ConfigurationManager.getProperty("oai", "storage"))) {
|
||||
DSpaceSolrServer.getServer();
|
||||
}
|
||||
System.out.println("[OAI 2.0] Initialized");
|
||||
}
|
||||
catch (com.lyncode.xoai.dataprovider.exceptions.ConfigurationException e)
|
||||
{
|
||||
System.out.println("Unable to configure XOAI (OAI 2.0 Core)");
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (SolrServerException e)
|
||||
{
|
||||
System.out.println("Unable to configure XOAI (OAI 2.0 Core)");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy()
|
||||
{
|
||||
System.out.println("[OAI 2.0] Destroyed");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest request,
|
||||
HttpServletResponse response) throws ServletException, IOException
|
||||
{
|
||||
request.setCharacterEncoding("UTF-8");
|
||||
Context context = null;
|
||||
|
||||
try
|
||||
{
|
||||
log.debug("OAI 2.0 request received");
|
||||
context = new Context();
|
||||
|
||||
// Filters require database connection -> dependency injection?
|
||||
for (AbstractFilter filter : XOAIManager.getManager()
|
||||
.getFilterManager().getFilters())
|
||||
if (filter instanceof DSpaceFilter)
|
||||
((DSpaceFilter) filter).initialize(context);
|
||||
|
||||
DSpaceItemRepository repository;
|
||||
String storage = ConfigurationManager
|
||||
.getProperty("oai", "storage");
|
||||
if (storage == null
|
||||
|| !storage.trim().toLowerCase().equals("database"))
|
||||
{
|
||||
log.debug("Using Solr for querying");
|
||||
repository = new DSpaceItemSolrRepository();
|
||||
}
|
||||
else
|
||||
{
|
||||
log.debug("Using Database for querying");
|
||||
repository = new DSpaceItemDatabaseRepository(context);
|
||||
}
|
||||
|
||||
log.debug("Creating OAI Data Provider Instance");
|
||||
OAIDataProvider dataProvider = new OAIDataProvider(request
|
||||
.getPathInfo().replace("/", ""), new DSpaceIdentify(
|
||||
context, request), new DSpaceSetRepository(context),
|
||||
repository);
|
||||
|
||||
log.debug("Reading parameters from request");
|
||||
|
||||
OutputStream out = response.getOutputStream();
|
||||
OAIRequestParameters parameters = new OAIRequestParameters();
|
||||
parameters.setFrom(request.getParameter("from"));
|
||||
parameters.setUntil(request.getParameter("until"));
|
||||
parameters.setSet(request.getParameter("set"));
|
||||
parameters.setVerb(request.getParameter("verb"));
|
||||
parameters
|
||||
.setMetadataPrefix(request.getParameter("metadataPrefix"));
|
||||
parameters.setIdentifier(request.getParameter("identifier"));
|
||||
parameters.setResumptionToken(request
|
||||
.getParameter("resumptionToken"));
|
||||
|
||||
response.setContentType("application/xml");
|
||||
|
||||
String identification = request.getPathInfo().replace("/", "")
|
||||
+ parameters.getVerb() + parameters.getMetadataPrefix()
|
||||
+ parameters.getIdentifier()
|
||||
+ parameters.getResumptionToken() + parameters.getSet()
|
||||
+ parameters.getFrom() + parameters.getUntil();
|
||||
|
||||
log.debug("Handling OAI request");
|
||||
XOAICacheManager.handle(identification, dataProvider, parameters, out);
|
||||
|
||||
out.flush();
|
||||
out.close();
|
||||
|
||||
if (context != null)
|
||||
context.abort();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.error(e.getMessage(), e);
|
||||
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
catch (InvalidContextException e)
|
||||
{
|
||||
log.error(e.getMessage(), e);
|
||||
if (context != null)
|
||||
context.abort();
|
||||
response.sendError(HttpServletResponse.SC_NOT_FOUND,
|
||||
"Requested OAI context \""
|
||||
+ request.getPathInfo().replace("/", "")
|
||||
+ "\" does not exist");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException
|
||||
{
|
||||
this.doGet(req, resp);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,527 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.xoai.app;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.ConnectException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.CommandLineParser;
|
||||
import org.apache.commons.cli.Options;
|
||||
import org.apache.commons.cli.PosixParser;
|
||||
import org.apache.log4j.LogManager;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.solr.client.solrj.SolrQuery;
|
||||
import org.apache.solr.client.solrj.SolrQuery.ORDER;
|
||||
import org.apache.solr.client.solrj.SolrServer;
|
||||
import org.apache.solr.client.solrj.SolrServerException;
|
||||
import org.apache.solr.common.SolrDocumentList;
|
||||
import org.apache.solr.common.SolrInputDocument;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.authorize.AuthorizeManager;
|
||||
import org.dspace.content.Bitstream;
|
||||
import org.dspace.content.Bundle;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.Community;
|
||||
import org.dspace.content.DCValue;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.ItemIterator;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.storage.rdbms.DatabaseManager;
|
||||
import org.dspace.storage.rdbms.TableRowIterator;
|
||||
import org.dspace.xoai.data.DSpaceDatabaseItem;
|
||||
import org.dspace.xoai.exceptions.CompilingException;
|
||||
import org.dspace.xoai.solr.DSpaceSolrSearch;
|
||||
import org.dspace.xoai.solr.DSpaceSolrServer;
|
||||
import org.dspace.xoai.solr.exceptions.DSpaceSolrException;
|
||||
import org.dspace.xoai.solr.exceptions.DSpaceSolrIndexerException;
|
||||
import org.dspace.xoai.util.ItemUtils;
|
||||
import org.dspace.xoai.util.XOAICacheManager;
|
||||
import org.dspace.xoai.util.XOAIDatabaseManager;
|
||||
|
||||
import com.lyncode.xoai.dataprovider.exceptions.MetadataBindException;
|
||||
import com.lyncode.xoai.dataprovider.util.MarshallingUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class XOAI
|
||||
{
|
||||
private static Logger log = LogManager.getLogger(XOAI.class);
|
||||
|
||||
private Context _context;
|
||||
|
||||
private boolean _optimize;
|
||||
|
||||
private boolean _verbose;
|
||||
|
||||
private boolean _clean;
|
||||
|
||||
private static List<String> getFileFormats(Item item)
|
||||
{
|
||||
List<String> formats = new ArrayList<String>();
|
||||
try
|
||||
{
|
||||
for (Bundle b : item.getBundles("ORIGINAL"))
|
||||
{
|
||||
for (Bitstream bs : b.getBitstreams())
|
||||
{
|
||||
if (!formats.contains(bs.getFormat().getMIMEType()))
|
||||
{
|
||||
formats.add(bs.getFormat().getMIMEType());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SQLException ex)
|
||||
{
|
||||
log.error(ex.getMessage(), ex);
|
||||
}
|
||||
return formats;
|
||||
}
|
||||
|
||||
public XOAI(Context context, boolean optimize, boolean clean, boolean verbose)
|
||||
{
|
||||
_context = context;
|
||||
_optimize = optimize;
|
||||
_clean = clean;
|
||||
_verbose = verbose;
|
||||
}
|
||||
|
||||
public XOAI(Context ctx, boolean hasOption)
|
||||
{
|
||||
_context = ctx;
|
||||
_verbose = hasOption;
|
||||
}
|
||||
|
||||
private void println(String line)
|
||||
{
|
||||
System.out.println(line);
|
||||
}
|
||||
|
||||
public int index() throws DSpaceSolrIndexerException
|
||||
{
|
||||
int result = 0;
|
||||
try
|
||||
{
|
||||
|
||||
if (_clean) {
|
||||
clearIndex();
|
||||
System.out.println("Using full import.");
|
||||
this.indexAll();
|
||||
} else {
|
||||
SolrQuery solrParams = new SolrQuery("*:*")
|
||||
.addField("item.lastmodified")
|
||||
.addSortField("item.lastmodified", ORDER.desc).setRows(1);
|
||||
|
||||
SolrDocumentList results = DSpaceSolrSearch.query(solrParams);
|
||||
if (results.getNumFound() == 0)
|
||||
{
|
||||
System.out.println("There are no indexed documents, using full import.");
|
||||
result = this.indexAll();
|
||||
}
|
||||
else
|
||||
result = this.index((Date) results.get(0).getFieldValue("item.lastmodified"));
|
||||
|
||||
}
|
||||
DSpaceSolrServer.getServer().commit();
|
||||
|
||||
|
||||
if (_optimize)
|
||||
{
|
||||
println("Optimizing Index");
|
||||
DSpaceSolrServer.getServer().optimize();
|
||||
println("Index optimized");
|
||||
}
|
||||
|
||||
// Set last compilation date
|
||||
XOAICacheManager.setLastCompilationDate(new Date());
|
||||
return result;
|
||||
}
|
||||
catch (DSpaceSolrException ex)
|
||||
{
|
||||
throw new DSpaceSolrIndexerException(ex.getMessage(), ex);
|
||||
}
|
||||
catch (SolrServerException ex)
|
||||
{
|
||||
throw new DSpaceSolrIndexerException(ex.getMessage(), ex);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
throw new DSpaceSolrIndexerException(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private int index(Date last) throws DSpaceSolrIndexerException
|
||||
{
|
||||
System.out
|
||||
.println("Incremental import. Searching for documents modified after: "
|
||||
+ last.toString());
|
||||
try
|
||||
{
|
||||
TableRowIterator iterator = DatabaseManager
|
||||
.query(_context,
|
||||
"SELECT item_id FROM item WHERE in_archive=TRUE AND last_modified > ?",
|
||||
new java.sql.Timestamp(last.getTime()));
|
||||
return this.index(iterator);
|
||||
}
|
||||
catch (SQLException ex)
|
||||
{
|
||||
throw new DSpaceSolrIndexerException(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private int indexAll() throws DSpaceSolrIndexerException
|
||||
{
|
||||
System.out.println("Full import");
|
||||
try
|
||||
{
|
||||
TableRowIterator iterator = DatabaseManager.query(_context,
|
||||
"SELECT item_id FROM item WHERE in_archive=TRUE");
|
||||
return this.index(iterator);
|
||||
}
|
||||
catch (SQLException ex)
|
||||
{
|
||||
throw new DSpaceSolrIndexerException(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private int index(TableRowIterator iterator)
|
||||
throws DSpaceSolrIndexerException
|
||||
{
|
||||
try
|
||||
{
|
||||
int i = 0;
|
||||
SolrServer server = DSpaceSolrServer.getServer();
|
||||
while (iterator.hasNext())
|
||||
{
|
||||
try
|
||||
{
|
||||
server.add(this.index(Item.find(_context, iterator.next()
|
||||
.getIntColumn("item_id"))));
|
||||
|
||||
_context.clearCache();
|
||||
}
|
||||
catch (SQLException ex)
|
||||
{
|
||||
log.error(ex.getMessage(), ex);
|
||||
}
|
||||
catch (MetadataBindException e)
|
||||
{
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
i++;
|
||||
if (i % 100 == 0) System.out.println(i+" items imported so far...");
|
||||
}
|
||||
System.out.println("Total: "+i+" items");
|
||||
server.commit();
|
||||
return i;
|
||||
}
|
||||
catch (SQLException ex)
|
||||
{
|
||||
throw new DSpaceSolrIndexerException(ex.getMessage(), ex);
|
||||
}
|
||||
catch (SolrServerException ex)
|
||||
{
|
||||
throw new DSpaceSolrIndexerException(ex.getMessage(), ex);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
throw new DSpaceSolrIndexerException(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private SolrInputDocument index(Item item) throws SQLException, MetadataBindException
|
||||
{
|
||||
SolrInputDocument doc = new SolrInputDocument();
|
||||
doc.addField("item.id", item.getID());
|
||||
boolean pub = this.isPublic(item);
|
||||
doc.addField("item.public", pub);
|
||||
String handle = item.getHandle();
|
||||
doc.addField("item.handle", handle);
|
||||
doc.addField("item.lastmodified", item.getLastModified());
|
||||
doc.addField("item.submitter", item.getSubmitter().getEmail());
|
||||
doc.addField("item.deleted", item.isWithdrawn() ? "true" : "false");
|
||||
for (Collection col : item.getCollections())
|
||||
doc.addField("item.collections",
|
||||
"col_" + col.getHandle().replace("/", "_"));
|
||||
for (Community com : XOAIDatabaseManager.flatParentCommunities(item))
|
||||
doc.addField("item.communities",
|
||||
"com_" + com.getHandle().replace("/", "_"));
|
||||
|
||||
DCValue[] allData = item.getMetadata(Item.ANY, Item.ANY, Item.ANY,
|
||||
Item.ANY);
|
||||
for (DCValue dc : allData)
|
||||
{
|
||||
String key = "metadata." + dc.schema + "." + dc.element;
|
||||
if (dc.qualifier != null)
|
||||
{
|
||||
key += "." + dc.qualifier;
|
||||
}
|
||||
doc.addField(key, dc.value);
|
||||
if (dc.authority != null) {
|
||||
doc.addField(key + ".authority", dc.authority);
|
||||
doc.addField(key + ".confidence", dc.confidence + "");
|
||||
}
|
||||
}
|
||||
|
||||
for (String f : getFileFormats(item))
|
||||
{
|
||||
doc.addField("metadata.dc.format.mimetype", f);
|
||||
}
|
||||
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
MarshallingUtils.writeMetadata(out, ItemUtils.retrieveMetadata(item));
|
||||
doc.addField("item.compile", out.toString());
|
||||
|
||||
if (_verbose)
|
||||
{
|
||||
println("Item with handle "+handle+" indexed");
|
||||
}
|
||||
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
private boolean isPublic(Item item)
|
||||
{
|
||||
try
|
||||
{
|
||||
AuthorizeManager.authorizeAction(_context, item, Constants.READ);
|
||||
for (Bundle b : item.getBundles())
|
||||
AuthorizeManager.authorizeAction(_context, b, Constants.READ);
|
||||
return true;
|
||||
}
|
||||
catch (AuthorizeException ex)
|
||||
{
|
||||
log.debug(ex.getMessage());
|
||||
}
|
||||
catch (SQLException ex)
|
||||
{
|
||||
log.error(ex.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private static boolean getKnownExplanation(Throwable t)
|
||||
{
|
||||
if (t instanceof ConnectException)
|
||||
{
|
||||
System.err.println("Solr server ("
|
||||
+ ConfigurationManager.getProperty("oai", "solr.url")
|
||||
+ ") is down, turn it on.");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean searchForReason(Throwable t)
|
||||
{
|
||||
if (getKnownExplanation(t))
|
||||
return true;
|
||||
if (t.getCause() != null)
|
||||
return searchForReason(t.getCause());
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void clearIndex() throws DSpaceSolrIndexerException
|
||||
{
|
||||
try
|
||||
{
|
||||
System.out.println("Clearing index");
|
||||
DSpaceSolrServer.getServer().deleteByQuery("*:*");
|
||||
DSpaceSolrServer.getServer().commit();
|
||||
System.out.println("Index cleared");
|
||||
}
|
||||
catch (SolrServerException ex)
|
||||
{
|
||||
throw new DSpaceSolrIndexerException(ex.getMessage(), ex);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
throw new DSpaceSolrIndexerException(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static void cleanCache()
|
||||
{
|
||||
System.out.println("Purging cached OAI responses.");
|
||||
XOAICacheManager.deleteCachedResponses();
|
||||
}
|
||||
|
||||
private static final String COMMAND_IMPORT = "import";
|
||||
private static final String COMMAND_CLEAN_CACHE = "clean-cache";
|
||||
private static final String COMMAND_COMPILE_ITEMS = "compile-items";
|
||||
private static final String COMMAND_ERASE_COMPILED_ITEMS = "erase-compiled-items";
|
||||
|
||||
public static void main(String[] argv)
|
||||
{
|
||||
try
|
||||
{
|
||||
CommandLineParser parser = new PosixParser();
|
||||
Options options = new Options();
|
||||
options.addOption("c", "clear", false, "Clear index before indexing");
|
||||
options.addOption("o", "optimize", false,
|
||||
"Optimize index at the end");
|
||||
options.addOption("v", "verbose", false, "Verbose output");
|
||||
options.addOption("h", "help", false, "Shows some help");
|
||||
options.addOption("n", "number", true, "FOR DEVELOPMENT MUST DELETE");
|
||||
CommandLine line = parser.parse(options, argv);
|
||||
|
||||
String[] validSolrCommands = { COMMAND_IMPORT, COMMAND_CLEAN_CACHE };
|
||||
String[] validDatabaseCommands = { COMMAND_CLEAN_CACHE, COMMAND_COMPILE_ITEMS, COMMAND_ERASE_COMPILED_ITEMS };
|
||||
|
||||
|
||||
boolean solr = true; // Assuming solr by default
|
||||
solr = !("database").equals(ConfigurationManager.getProperty("oai", "storage"));
|
||||
|
||||
|
||||
boolean run = false;
|
||||
if (line.getArgs().length > 0) {
|
||||
if (solr) {
|
||||
if (Arrays.asList(validSolrCommands).contains(line.getArgs()[0])) {
|
||||
run = true;
|
||||
}
|
||||
} else {
|
||||
if (Arrays.asList(validDatabaseCommands).contains(line.getArgs()[0])) {
|
||||
run = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!line.hasOption('h') && run) {
|
||||
System.out.println("OAI 2.0 manager action started");
|
||||
long start = System.currentTimeMillis();
|
||||
|
||||
String command = line.getArgs()[0];
|
||||
|
||||
if (COMMAND_IMPORT.equals(command)) {
|
||||
Context ctx = new Context();
|
||||
XOAI indexer = new XOAI(ctx,
|
||||
line.hasOption('o'),
|
||||
line.hasOption('c'),
|
||||
line.hasOption('v'));
|
||||
|
||||
int imported = indexer.index();
|
||||
if (imported > 0) cleanCache();
|
||||
|
||||
ctx.abort();
|
||||
} else if (COMMAND_CLEAN_CACHE.equals(command)) {
|
||||
cleanCache();
|
||||
} else if (COMMAND_COMPILE_ITEMS.equals(command)) {
|
||||
|
||||
Context ctx = new Context();
|
||||
XOAI indexer = new XOAI(ctx, line.hasOption('v'));
|
||||
|
||||
indexer.compile();
|
||||
|
||||
cleanCache();
|
||||
|
||||
ctx.abort();
|
||||
} else if (COMMAND_ERASE_COMPILED_ITEMS.equals(command)) {
|
||||
cleanCompiledItems();
|
||||
cleanCache();
|
||||
}
|
||||
|
||||
System.out.println("OAI 2.0 manager action ended. It took "
|
||||
+ ((System.currentTimeMillis() - start) / 1000)
|
||||
+ " seconds.");
|
||||
} else {
|
||||
usage();
|
||||
}
|
||||
}
|
||||
catch (Throwable ex)
|
||||
{
|
||||
if (!searchForReason(ex))
|
||||
{
|
||||
ex.printStackTrace();
|
||||
}
|
||||
log.error(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static void cleanCompiledItems()
|
||||
{
|
||||
System.out.println("Purging compiled items");
|
||||
XOAICacheManager.deleteCompiledItems();
|
||||
}
|
||||
|
||||
private void compile() throws CompilingException
|
||||
{
|
||||
ItemIterator iterator;
|
||||
try
|
||||
{
|
||||
Date last = XOAICacheManager.getLastCompilationDate();
|
||||
|
||||
if (last == null) {
|
||||
System.out.println("Retrieving all items to be compiled");
|
||||
iterator = Item.findAll(_context);
|
||||
} else {
|
||||
System.out.println("Retrieving items modified after "+last+" to be compiled");
|
||||
String query = "SELECT * FROM item WHERE last_modified>?";
|
||||
iterator = new ItemIterator(_context, DatabaseManager.query(_context, query, new java.sql.Date(last.getTime())));
|
||||
}
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
Item item = iterator.next();
|
||||
if (_verbose) System.out.println("Compiling item with handle: "+ item.getHandle());
|
||||
XOAICacheManager.compileItem(new DSpaceDatabaseItem(item));
|
||||
_context.clearCache();
|
||||
}
|
||||
|
||||
XOAICacheManager.setLastCompilationDate(new Date());
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
throw new CompilingException(e);
|
||||
}
|
||||
System.out.println("Items compiled");
|
||||
}
|
||||
|
||||
private static void usage()
|
||||
{
|
||||
boolean solr = true; // Assuming solr by default
|
||||
solr = !("database").equals(ConfigurationManager.getProperty("oai", "storage"));
|
||||
|
||||
if (solr) {
|
||||
System.out.println("OAI Manager Script");
|
||||
System.out.println("Syntax: oai <action> [parameters]");
|
||||
System.out.println("> Possible actions:");
|
||||
System.out.println(" "+COMMAND_IMPORT+" - To import DSpace items into OAI index and cache system");
|
||||
System.out.println(" "+COMMAND_CLEAN_CACHE+" - Cleans the OAI cached responses");
|
||||
System.out.println("> Parameters:");
|
||||
System.out.println(" -o Optimize index after indexing ("+COMMAND_IMPORT+" only)");
|
||||
System.out.println(" -c Clear index ("+COMMAND_IMPORT+" only)");
|
||||
System.out.println(" -v Verbose output");
|
||||
System.out.println(" -h Shows this text");
|
||||
} else {
|
||||
System.out.println("OAI Manager Script");
|
||||
System.out.println("Syntax: oai <action> [parameters]");
|
||||
System.out.println("> Possible actions:");
|
||||
System.out.println(" "+COMMAND_CLEAN_CACHE+" - Cleans the OAI cached responses");
|
||||
System.out.println(" "+COMMAND_COMPILE_ITEMS+" - Compiles all DSpace items");
|
||||
System.out.println(" "+COMMAND_ERASE_COMPILED_ITEMS+" - Erase the OAI compiled items");
|
||||
System.out.println("> Parameters:");
|
||||
System.out.println(" -v Verbose output");
|
||||
System.out.println(" -h Shows this text");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.xoai.data;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.log4j.LogManager;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.Community;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.xoai.util.XOAICacheManager;
|
||||
import org.dspace.xoai.util.XOAIDatabaseManager;
|
||||
|
||||
import com.lyncode.xoai.dataprovider.core.ItemMetadata;
|
||||
import com.lyncode.xoai.dataprovider.core.ReferenceSet;
|
||||
import com.lyncode.xoai.dataprovider.data.AbstractAbout;
|
||||
import com.lyncode.xoai.dataprovider.exceptions.MetadataBindException;
|
||||
import com.lyncode.xoai.dataprovider.xml.xoai.Element;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
public class DSpaceDatabaseItem extends DSpaceItem
|
||||
{
|
||||
private static Logger log = LogManager.getLogger(DSpaceDatabaseItem.class);
|
||||
|
||||
private static List<ReferenceSet> getSets(Item item)
|
||||
{
|
||||
List<ReferenceSet> sets = new ArrayList<ReferenceSet>();
|
||||
List<Community> coms = new ArrayList<Community>();
|
||||
try
|
||||
{
|
||||
Collection[] itemCollections = item.getCollections();
|
||||
for (Collection col : itemCollections)
|
||||
{
|
||||
ReferenceSet s = new DSpaceSet(col);
|
||||
sets.add(s);
|
||||
for (Community com : XOAIDatabaseManager
|
||||
.flatParentCommunities(col))
|
||||
if (!coms.contains(com))
|
||||
coms.add(com);
|
||||
}
|
||||
for (Community com : coms)
|
||||
{
|
||||
ReferenceSet s = new DSpaceSet(com);
|
||||
sets.add(s);
|
||||
}
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return sets;
|
||||
}
|
||||
|
||||
private Item item;
|
||||
private List<ReferenceSet> sets;
|
||||
|
||||
public DSpaceDatabaseItem(Item item)
|
||||
{
|
||||
this.item = item;
|
||||
this.sets = getSets(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AbstractAbout> getAbout()
|
||||
{
|
||||
return new ArrayList<AbstractAbout>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getDatestamp()
|
||||
{
|
||||
return item.getLastModified();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ReferenceSet> getSets()
|
||||
{
|
||||
return sets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDeleted()
|
||||
{
|
||||
return item.isWithdrawn();
|
||||
}
|
||||
|
||||
private static Element getElement(List<Element> list, String name)
|
||||
{
|
||||
for (Element e : list)
|
||||
if (name.equals(e.getName()))
|
||||
return e;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private ItemMetadata metadata = null;
|
||||
|
||||
@Override
|
||||
public ItemMetadata getMetadata()
|
||||
{
|
||||
if (metadata == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
metadata = new ItemMetadata(XOAICacheManager.getCompiledMetadata(this));
|
||||
}
|
||||
catch (MetadataBindException e)
|
||||
{
|
||||
log.warn(e.getMessage(), e);
|
||||
metadata = new ItemMetadata(XOAICacheManager.getMetadata(this));
|
||||
}
|
||||
}
|
||||
return metadata;
|
||||
}
|
||||
|
||||
private List<String> getMetadata(List<Element> elems, String[] parts)
|
||||
{
|
||||
List<String> list = new ArrayList<String>();
|
||||
if (parts.length > 1)
|
||||
{
|
||||
if (parts[0].equals("*"))
|
||||
{
|
||||
for (Element e : elems)
|
||||
{
|
||||
if (e.getElement() != null)
|
||||
list.addAll(this.getMetadata(e.getElement(),
|
||||
Arrays.copyOfRange(parts, 1, parts.length)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Element e = getElement(elems, parts[0]);
|
||||
if (e != null)
|
||||
list.addAll(this.getMetadata(e.getElement(),
|
||||
Arrays.copyOfRange(parts, 1, parts.length)));
|
||||
}
|
||||
}
|
||||
else if (parts.length == 1)
|
||||
{
|
||||
// Here we could have reached our target (named fields)
|
||||
for (Element e : elems)
|
||||
{
|
||||
for (Element.Field f : e.getField())
|
||||
{
|
||||
if (parts[0].equals("*"))
|
||||
list.add(f.getValue());
|
||||
else if (parts[0].equals(f.getName()))
|
||||
list.add(f.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
if (parts[0].equals("*"))
|
||||
{
|
||||
for (Element e : elems)
|
||||
{
|
||||
if (e.getElement() != null)
|
||||
list.addAll(this.getMetadata(e.getElement(),
|
||||
Arrays.copyOfRange(parts, 1, parts.length)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Element e = getElement(elems, parts[0]);
|
||||
if (e != null)
|
||||
list.addAll(this.getMetadata(e.getElement(),
|
||||
Arrays.copyOfRange(parts, 1, parts.length)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Here we have reached our target (unnamed fields)
|
||||
for (Element e : elems)
|
||||
{
|
||||
for (Element.Field f : e.getField())
|
||||
{
|
||||
if (f.getName() == null || f.getName().equals(""))
|
||||
list.add(f.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public List<String> getMetadata(String field)
|
||||
{
|
||||
String[] parts = field.split(Pattern.quote("."));
|
||||
return getMetadata(this.getMetadata().getMetadata().getElement(), parts);
|
||||
}
|
||||
|
||||
public Item getItem()
|
||||
{
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getHandle()
|
||||
{
|
||||
return item.getHandle();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.xoai.data;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.log4j.LogManager;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.storage.rdbms.DatabaseManager;
|
||||
import org.dspace.storage.rdbms.TableRowIterator;
|
||||
import org.dspace.xoai.exceptions.InvalidMetadataFieldException;
|
||||
import org.dspace.xoai.util.DateUtils;
|
||||
import org.dspace.xoai.util.MetadataFieldManager;
|
||||
|
||||
import com.lyncode.xoai.dataprovider.core.DeleteMethod;
|
||||
import com.lyncode.xoai.dataprovider.core.Granularity;
|
||||
import com.lyncode.xoai.dataprovider.data.AbstractIdentify;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
public class DSpaceIdentify extends AbstractIdentify
|
||||
{
|
||||
private static Logger log = LogManager.getLogger(DSpaceIdentify.class);
|
||||
|
||||
private static List<String> _emails = null;
|
||||
|
||||
private static String _name = null;
|
||||
|
||||
private static String _baseUrl = null;
|
||||
|
||||
private Context _context;
|
||||
|
||||
private HttpServletRequest _request;
|
||||
|
||||
public DSpaceIdentify(Context context, HttpServletRequest request)
|
||||
{
|
||||
_context = context;
|
||||
_request = request;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAdminEmails()
|
||||
{
|
||||
if (_emails == null)
|
||||
{
|
||||
_emails = new ArrayList<String>();
|
||||
String result = ConfigurationManager.getProperty("mail.admin");
|
||||
if (result == null)
|
||||
{
|
||||
log.warn("{ OAI 2.0 :: DSpace } Not able to retrieve the mail.admin property from the configuration file");
|
||||
}
|
||||
else
|
||||
_emails.add(result);
|
||||
}
|
||||
return _emails;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBaseUrl()
|
||||
{
|
||||
if (_baseUrl == null)
|
||||
{
|
||||
_baseUrl = _request.getRequestURL().toString()
|
||||
.replace(_request.getPathInfo(), "");
|
||||
}
|
||||
return _baseUrl + _request.getPathInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeleteMethod getDeleteMethod()
|
||||
{
|
||||
return DeleteMethod.PERSISTENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getEarliestDate()
|
||||
{
|
||||
// Look at the database!
|
||||
try
|
||||
{
|
||||
TableRowIterator iterator = DatabaseManager
|
||||
.query(_context,
|
||||
"SELECT MIN(text_value) as value FROM metadatavalue WHERE metadata_field_id = ?",
|
||||
MetadataFieldManager.getFieldID(_context,
|
||||
"dc.date.available"));
|
||||
|
||||
if (iterator.hasNext())
|
||||
{
|
||||
String str = iterator.next().getStringColumn("value");
|
||||
try
|
||||
{
|
||||
Date d = DateUtils.parseDate(str);
|
||||
if (d != null)
|
||||
return d;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
catch (InvalidMetadataFieldException e)
|
||||
{
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return new Date();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Granularity getGranularity()
|
||||
{
|
||||
return Granularity.Second;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRepositoryName()
|
||||
{
|
||||
if (_name == null)
|
||||
{
|
||||
_name = ConfigurationManager.getProperty("dspace.name");
|
||||
if (_name == null)
|
||||
{
|
||||
log.warn("{ OAI 2.0 :: DSpace } Not able to retrieve the dspace.name property from the configuration file");
|
||||
_name = "OAI Repository";
|
||||
}
|
||||
}
|
||||
return _name;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.xoai.data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
|
||||
import com.lyncode.xoai.dataprovider.data.AbstractAbout;
|
||||
import com.lyncode.xoai.dataprovider.data.AbstractItem;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
public abstract class DSpaceItem extends AbstractItem
|
||||
{
|
||||
|
||||
@Override
|
||||
public List<AbstractAbout> getAbout()
|
||||
{
|
||||
return new ArrayList<AbstractAbout>();
|
||||
}
|
||||
|
||||
protected abstract String getHandle ();
|
||||
|
||||
private String _prefix = null;
|
||||
|
||||
@Override
|
||||
public String getIdentifier()
|
||||
{
|
||||
if (_prefix == null)
|
||||
{
|
||||
_prefix = ConfigurationManager.getProperty("oai",
|
||||
"identifier.prefix");
|
||||
}
|
||||
return "oai:" + _prefix + ":" + this.getHandle();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.xoai.data;
|
||||
|
||||
import com.lyncode.xoai.dataprovider.core.ListItemIdentifiersResult;
|
||||
import com.lyncode.xoai.dataprovider.core.ListItemsResults;
|
||||
import com.lyncode.xoai.dataprovider.data.AbstractItem;
|
||||
import com.lyncode.xoai.dataprovider.data.AbstractItemIdentifier;
|
||||
import com.lyncode.xoai.dataprovider.exceptions.IdDoesNotExistException;
|
||||
import com.lyncode.xoai.dataprovider.filter.Filter;
|
||||
import com.lyncode.xoai.dataprovider.filter.FilterScope;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.log4j.LogManager;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.ItemIterator;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.handle.HandleManager;
|
||||
import org.dspace.storage.rdbms.DatabaseManager;
|
||||
import org.dspace.storage.rdbms.TableRowIterator;
|
||||
import org.dspace.xoai.filter.DSpaceFilter;
|
||||
import org.dspace.xoai.filter.DatabaseFilterResult;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
public class DSpaceItemDatabaseRepository extends DSpaceItemRepository
|
||||
{
|
||||
|
||||
private static Logger log = LogManager
|
||||
.getLogger(DSpaceItemDatabaseRepository.class);
|
||||
|
||||
private Context _context;
|
||||
|
||||
public DSpaceItemDatabaseRepository(Context context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractItem getItem(String id) throws IdDoesNotExistException
|
||||
{
|
||||
try
|
||||
{
|
||||
String parts[] = id.split(Pattern.quote(":"));
|
||||
if (parts.length == 3)
|
||||
{
|
||||
DSpaceObject obj = HandleManager.resolveToObject(_context,
|
||||
parts[2]);
|
||||
if (obj == null)
|
||||
throw new IdDoesNotExistException();
|
||||
if (!(obj instanceof Item))
|
||||
throw new IdDoesNotExistException();
|
||||
return new DSpaceDatabaseItem((Item) obj);
|
||||
}
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
log.debug(e.getMessage(), e);
|
||||
throw new IdDoesNotExistException();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.error(e.getMessage(), e);
|
||||
throw new IdDoesNotExistException();
|
||||
}
|
||||
throw new IdDoesNotExistException();
|
||||
}
|
||||
|
||||
private ListItemIdentifiersResult getIdentifierResult(String query, String countQuery,
|
||||
List<Object> countParameters,
|
||||
List<Object> parameters, int length)
|
||||
{
|
||||
boolean hasMore = false;
|
||||
List<AbstractItemIdentifier> list = new ArrayList<AbstractItemIdentifier>();
|
||||
TableRowIterator rows;
|
||||
int count = -1;
|
||||
try
|
||||
{
|
||||
count = DatabaseManager.querySingle(_context, countQuery, countParameters).getIntColumn("count");
|
||||
}
|
||||
catch (SQLException e1)
|
||||
{
|
||||
log.error("Unable to retrieve number of items that match");
|
||||
}
|
||||
try
|
||||
{
|
||||
parameters.add(length + 1);
|
||||
rows = DatabaseManager.queryTable(_context, "item", query,
|
||||
parameters.toArray());
|
||||
ItemIterator iterator = new ItemIterator(_context, rows);
|
||||
int i = 0;
|
||||
while (iterator.hasNext() && i < length)
|
||||
{
|
||||
list.add(new DSpaceDatabaseItem(iterator.next()));
|
||||
i++;
|
||||
}
|
||||
hasMore = iterator.hasNext();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return new ListItemIdentifiersResult(hasMore, list, count);
|
||||
}
|
||||
|
||||
private ListItemsResults getResult(String query, String countQuery, List<Object> countParameters, List<Object> parameters, int length)
|
||||
{
|
||||
boolean hasMore = false;
|
||||
List<AbstractItem> list = new ArrayList<AbstractItem>();
|
||||
TableRowIterator rows;
|
||||
int count = -1;
|
||||
try
|
||||
{
|
||||
count = DatabaseManager.querySingle(_context, countQuery, countParameters).getIntColumn("count");
|
||||
}
|
||||
catch (SQLException e1)
|
||||
{
|
||||
log.error("Unable to retrieve number of items that match");
|
||||
}
|
||||
try
|
||||
{
|
||||
|
||||
parameters.add(length + 1);
|
||||
rows = DatabaseManager.queryTable(_context, "item", query,
|
||||
parameters.toArray());
|
||||
ItemIterator iterator = new ItemIterator(_context, rows);
|
||||
int i = 0;
|
||||
while (iterator.hasNext() && i < length)
|
||||
{
|
||||
list.add(new DSpaceDatabaseItem(iterator.next()));
|
||||
i++;
|
||||
}
|
||||
hasMore = iterator.hasNext();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return new ListItemsResults(hasMore, list, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ListItemsResults getItems(List<Filter> filters, int offset,
|
||||
int length)
|
||||
{
|
||||
List<Object> parameters = new ArrayList<Object>();
|
||||
List<Object> countParameters = new ArrayList<Object>();
|
||||
String query = "SELECT i.* FROM item i ";
|
||||
String countQuery = "SELECT COUNT(*) as count FROM item i";
|
||||
List<String> whereCond = new ArrayList<String>();
|
||||
for (Filter filter : filters)
|
||||
{
|
||||
if (filter.getFilter() instanceof DSpaceFilter)
|
||||
{
|
||||
DSpaceFilter dspaceFilter = (DSpaceFilter) filter.getFilter();
|
||||
DatabaseFilterResult result = dspaceFilter.getWhere(_context);
|
||||
if (result.hasResult())
|
||||
{
|
||||
if (filter.getScope() == FilterScope.MetadataFormat)
|
||||
whereCond.add("(i.withdrawn=TRUE OR ("
|
||||
+ result.getWhere() + "))");
|
||||
else
|
||||
whereCond.add("(" + result.getWhere() + ")");
|
||||
parameters.addAll(result.getParameters());
|
||||
countParameters.addAll(result.getParameters());
|
||||
}
|
||||
}
|
||||
}
|
||||
String where = StringUtils.join(whereCond.iterator(), " AND ");
|
||||
if (!where.equals("")) {
|
||||
query += " WHERE " + where;
|
||||
countQuery += " WHERE " + where;
|
||||
}
|
||||
|
||||
query += " ORDER BY i.item_id";
|
||||
String db = ConfigurationManager.getProperty("db.name");
|
||||
boolean postgres = true;
|
||||
// Assuming Postgres as default
|
||||
if ("oracle".equals(db))
|
||||
postgres = false;
|
||||
if (postgres)
|
||||
{
|
||||
query += " OFFSET ? LIMIT ?";
|
||||
}
|
||||
else
|
||||
{
|
||||
// Oracle
|
||||
query = "SELECT *, ROWNUM r FROM (" + query
|
||||
+ ") WHERE r BETWEEN ? AND ?";
|
||||
length = length + offset;
|
||||
}
|
||||
parameters.add(offset);
|
||||
return this.getResult(query, countQuery, countParameters, parameters, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ListItemIdentifiersResult getItemIdentifiers(
|
||||
List<Filter> filters, int offset, int length)
|
||||
{
|
||||
List<Object> parameters = new ArrayList<Object>();
|
||||
List<Object> countParameters = new ArrayList<Object>();
|
||||
String query = "SELECT i.* FROM item i ";
|
||||
String countQuery = "SELECT COUNT(*) as count FROM item i";
|
||||
List<String> whereCond = new ArrayList<String>();
|
||||
for (Filter filter : filters)
|
||||
{
|
||||
if (filter.getFilter() instanceof DSpaceFilter)
|
||||
{
|
||||
DSpaceFilter dspaceFilter = (DSpaceFilter) filter.getFilter();
|
||||
DatabaseFilterResult result = dspaceFilter.getWhere(_context);
|
||||
if (result.hasResult())
|
||||
{
|
||||
if (filter.getScope() == FilterScope.MetadataFormat)
|
||||
whereCond.add("(i.withdrawn=TRUE OR ("
|
||||
+ result.getWhere() + "))");
|
||||
else
|
||||
whereCond.add("(" + result.getWhere() + ")");
|
||||
parameters.addAll(result.getParameters());
|
||||
countParameters.addAll(result.getParameters());
|
||||
}
|
||||
}
|
||||
}
|
||||
String where = StringUtils.join(whereCond.iterator(), " AND ");
|
||||
if (!where.equals("")) {
|
||||
query += " WHERE " + where;
|
||||
countQuery += " WHERE "+ where;
|
||||
}
|
||||
query += " ORDER BY i.item_id";
|
||||
String db = ConfigurationManager.getProperty("db.name");
|
||||
boolean postgres = true;
|
||||
// Assuming Postgres as default
|
||||
if ("oracle".equals(db))
|
||||
postgres = false;
|
||||
if (postgres)
|
||||
{
|
||||
query += " OFFSET ? LIMIT ?";
|
||||
}
|
||||
else
|
||||
{
|
||||
// Oracle
|
||||
query = "SELECT *, ROWNUM r FROM (" + query
|
||||
+ ") WHERE r BETWEEN ? AND ?";
|
||||
length = length + offset;
|
||||
}
|
||||
parameters.add(offset);
|
||||
return this.getIdentifierResult(query, countQuery, countParameters, parameters, length);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.xoai.data;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.dspace.xoai.filter.DateFromFilter;
|
||||
import org.dspace.xoai.filter.DateUntilFilter;
|
||||
import org.dspace.xoai.filter.DspaceSetSpecFilter;
|
||||
|
||||
import com.lyncode.xoai.dataprovider.core.ListItemIdentifiersResult;
|
||||
import com.lyncode.xoai.dataprovider.core.ListItemsResults;
|
||||
import com.lyncode.xoai.dataprovider.data.AbstractItemRepository;
|
||||
import com.lyncode.xoai.dataprovider.filter.Filter;
|
||||
import com.lyncode.xoai.dataprovider.filter.FilterScope;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
public abstract class DSpaceItemRepository extends AbstractItemRepository
|
||||
{
|
||||
|
||||
// private static Logger log =
|
||||
// LogManager.getLogger(DSpaceItemRepository.class);
|
||||
@Override
|
||||
protected ListItemIdentifiersResult getItemIdentifiers(
|
||||
List<Filter> filters, int offset, int length, Date from)
|
||||
{
|
||||
filters.add(new Filter(new DateFromFilter(from), FilterScope.Query));
|
||||
return this.getItemIdentifiers(filters, offset, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ListItemIdentifiersResult getItemIdentifiers(
|
||||
List<Filter> filters, int offset, int length, String setSpec)
|
||||
{
|
||||
filters.add(new Filter(new DspaceSetSpecFilter(setSpec),
|
||||
FilterScope.Query));
|
||||
return this.getItemIdentifiers(filters, offset, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ListItemIdentifiersResult getItemIdentifiers(
|
||||
List<Filter> filters, int offset, int length, Date from, Date until)
|
||||
{
|
||||
filters.add(new Filter(new DateFromFilter(from), FilterScope.Query));
|
||||
filters.add(new Filter(new DateUntilFilter(until), FilterScope.Query));
|
||||
return this.getItemIdentifiers(filters, offset, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ListItemIdentifiersResult getItemIdentifiers(
|
||||
List<Filter> filters, int offset, int length, String setSpec,
|
||||
Date from)
|
||||
{
|
||||
filters.add(new Filter(new DateFromFilter(from), FilterScope.Query));
|
||||
filters.add(new Filter(new DspaceSetSpecFilter(setSpec),
|
||||
FilterScope.Query));
|
||||
return this.getItemIdentifiers(filters, offset, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ListItemIdentifiersResult getItemIdentifiers(
|
||||
List<Filter> filters, int offset, int length, String setSpec,
|
||||
Date from, Date until)
|
||||
{
|
||||
filters.add(new Filter(new DateFromFilter(from), FilterScope.Query));
|
||||
filters.add(new Filter(new DateUntilFilter(until), FilterScope.Query));
|
||||
filters.add(new Filter(new DspaceSetSpecFilter(setSpec),
|
||||
FilterScope.Query));
|
||||
return this.getItemIdentifiers(filters, offset, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ListItemIdentifiersResult getItemIdentifiersUntil(
|
||||
List<Filter> filters, int offset, int length, Date until)
|
||||
{
|
||||
filters.add(new Filter(new DateUntilFilter(until), FilterScope.Query));
|
||||
return this.getItemIdentifiers(filters, offset, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ListItemIdentifiersResult getItemIdentifiersUntil(
|
||||
List<Filter> filters, int offset, int length, String setSpec,
|
||||
Date until)
|
||||
{
|
||||
filters.add(new Filter(new DateUntilFilter(until), FilterScope.Query));
|
||||
filters.add(new Filter(new DspaceSetSpecFilter(setSpec),
|
||||
FilterScope.Query));
|
||||
return this.getItemIdentifiers(filters, offset, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ListItemsResults getItems(List<Filter> filters, int offset,
|
||||
int length, Date from)
|
||||
{
|
||||
filters.add(new Filter(new DateFromFilter(from), FilterScope.Query));
|
||||
return this.getItems(filters, offset, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ListItemsResults getItems(List<Filter> filters, int offset,
|
||||
int length, String setSpec)
|
||||
{
|
||||
filters.add(new Filter(new DspaceSetSpecFilter(setSpec),
|
||||
FilterScope.Query));
|
||||
return this.getItems(filters, offset, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ListItemsResults getItems(List<Filter> filters, int offset,
|
||||
int length, Date from, Date until)
|
||||
{
|
||||
filters.add(new Filter(new DateFromFilter(from), FilterScope.Query));
|
||||
filters.add(new Filter(new DateUntilFilter(until), FilterScope.Query));
|
||||
return this.getItems(filters, offset, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ListItemsResults getItems(List<Filter> filters, int offset,
|
||||
int length, String setSpec, Date from)
|
||||
{
|
||||
filters.add(new Filter(new DateFromFilter(from), FilterScope.Query));
|
||||
filters.add(new Filter(new DspaceSetSpecFilter(setSpec),
|
||||
FilterScope.Query));
|
||||
return this.getItems(filters, offset, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ListItemsResults getItems(List<Filter> filters, int offset,
|
||||
int length, String setSpec, Date from, Date until)
|
||||
{
|
||||
filters.add(new Filter(new DateFromFilter(from), FilterScope.Query));
|
||||
filters.add(new Filter(new DateUntilFilter(until), FilterScope.Query));
|
||||
filters.add(new Filter(new DspaceSetSpecFilter(setSpec),
|
||||
FilterScope.Query));
|
||||
return this.getItems(filters, offset, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ListItemsResults getItemsUntil(List<Filter> filters, int offset,
|
||||
int length, Date until)
|
||||
{
|
||||
filters.add(new Filter(new DateUntilFilter(until), FilterScope.Query));
|
||||
return this.getItems(filters, offset, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ListItemsResults getItemsUntil(List<Filter> filters, int offset,
|
||||
int length, String setSpec, Date from)
|
||||
{
|
||||
filters.add(new Filter(new DateFromFilter(from), FilterScope.Query));
|
||||
filters.add(new Filter(new DspaceSetSpecFilter(setSpec),
|
||||
FilterScope.Query));
|
||||
return this.getItems(filters, offset, length);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.xoai.data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.log4j.LogManager;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.solr.client.solrj.SolrQuery;
|
||||
import org.apache.solr.common.SolrDocument;
|
||||
import org.apache.solr.common.SolrDocumentList;
|
||||
import org.dspace.xoai.filter.DSpaceFilter;
|
||||
import org.dspace.xoai.filter.SolrFilterResult;
|
||||
import org.dspace.xoai.solr.DSpaceSolrSearch;
|
||||
import org.dspace.xoai.solr.exceptions.DSpaceSolrException;
|
||||
import org.dspace.xoai.solr.exceptions.SolrSearchEmptyException;
|
||||
|
||||
import com.lyncode.xoai.dataprovider.core.ListItemIdentifiersResult;
|
||||
import com.lyncode.xoai.dataprovider.core.ListItemsResults;
|
||||
import com.lyncode.xoai.dataprovider.data.AbstractItem;
|
||||
import com.lyncode.xoai.dataprovider.data.AbstractItemIdentifier;
|
||||
import com.lyncode.xoai.dataprovider.exceptions.IdDoesNotExistException;
|
||||
import com.lyncode.xoai.dataprovider.filter.Filter;
|
||||
import com.lyncode.xoai.dataprovider.filter.FilterScope;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
public class DSpaceItemSolrRepository extends DSpaceItemRepository
|
||||
{
|
||||
private static Logger log = LogManager.getLogger(DSpaceItemSolrRepository.class);
|
||||
|
||||
public DSpaceItemSolrRepository()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractItem getItem(String identifier)
|
||||
throws IdDoesNotExistException
|
||||
{
|
||||
String parts[] = identifier.split(Pattern.quote(":"));
|
||||
if (parts.length == 3)
|
||||
{
|
||||
try
|
||||
{
|
||||
SolrQuery params = new SolrQuery("item.handle:" + parts[2]);
|
||||
return new DSpaceSolrItem(DSpaceSolrSearch.querySingle(params));
|
||||
}
|
||||
catch (SolrSearchEmptyException ex)
|
||||
{
|
||||
throw new IdDoesNotExistException(ex);
|
||||
}
|
||||
}
|
||||
throw new IdDoesNotExistException();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ListItemIdentifiersResult getItemIdentifiers(
|
||||
List<Filter> filters, int offset, int length)
|
||||
{
|
||||
List<String> whereCond = new ArrayList<String>();
|
||||
for (Filter filter : filters)
|
||||
{
|
||||
if (filter.getFilter() instanceof DSpaceFilter)
|
||||
{
|
||||
DSpaceFilter dspaceFilter = (DSpaceFilter) filter.getFilter();
|
||||
SolrFilterResult result = dspaceFilter.getQuery();
|
||||
if (result.hasResult())
|
||||
{
|
||||
if (filter.getScope() == FilterScope.MetadataFormat)
|
||||
whereCond.add("(item.deleted:true OR ("
|
||||
+ result.getQuery() + "))");
|
||||
else
|
||||
whereCond.add("(" + result.getQuery() + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (whereCond.isEmpty())
|
||||
whereCond.add("*:*");
|
||||
String where = "(" + StringUtils.join(whereCond.iterator(), ") AND (")
|
||||
+ ")";
|
||||
return this.getIdentifierResult(where, offset, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ListItemsResults getItems(List<Filter> filters, int offset,
|
||||
int length)
|
||||
{
|
||||
List<String> whereCond = new ArrayList<String>();
|
||||
for (Filter filter : filters)
|
||||
{
|
||||
if (filter.getFilter() instanceof DSpaceFilter)
|
||||
{
|
||||
DSpaceFilter dspaceFilter = (DSpaceFilter) filter.getFilter();
|
||||
SolrFilterResult result = dspaceFilter.getQuery();
|
||||
if (result.hasResult())
|
||||
{
|
||||
if (filter.getScope() == FilterScope.MetadataFormat)
|
||||
whereCond.add("(item.deleted:true OR ("
|
||||
+ result.getQuery() + "))");
|
||||
else
|
||||
whereCond.add("(" + result.getQuery() + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (whereCond.isEmpty())
|
||||
whereCond.add("*:*");
|
||||
String where = "(" + StringUtils.join(whereCond.iterator(), ") AND (")
|
||||
+ ")";
|
||||
return this.getResult(where, offset, length);
|
||||
}
|
||||
|
||||
private ListItemsResults getResult(String where, int offset, int length)
|
||||
{
|
||||
List<AbstractItem> list = new ArrayList<AbstractItem>();
|
||||
try
|
||||
{
|
||||
SolrQuery params = new SolrQuery(where).setRows(length).setStart(
|
||||
offset);
|
||||
SolrDocumentList docs = DSpaceSolrSearch.query(params);
|
||||
for (SolrDocument doc : docs)
|
||||
{
|
||||
list.add(new DSpaceSolrItem(doc));
|
||||
}
|
||||
return new ListItemsResults((docs.getNumFound() > offset + length),
|
||||
list, (int) docs.getNumFound());
|
||||
}
|
||||
catch (DSpaceSolrException ex)
|
||||
{
|
||||
log.error(ex.getMessage(), ex);
|
||||
return new ListItemsResults(false, list);
|
||||
}
|
||||
}
|
||||
|
||||
private ListItemIdentifiersResult getIdentifierResult(String where,
|
||||
int offset, int length)
|
||||
{
|
||||
List<AbstractItemIdentifier> list = new ArrayList<AbstractItemIdentifier>();
|
||||
try
|
||||
{
|
||||
SolrQuery params = new SolrQuery(where).setRows(length).setStart(
|
||||
offset);
|
||||
boolean hasMore = false;
|
||||
SolrDocumentList docs = DSpaceSolrSearch.query(params);
|
||||
hasMore = (offset + length) < docs.getNumFound();
|
||||
for (SolrDocument doc : docs)
|
||||
{
|
||||
list.add(new DSpaceSolrItem(doc));
|
||||
}
|
||||
return new ListItemIdentifiersResult(hasMore, list, (int) docs.getNumFound());
|
||||
}
|
||||
catch (DSpaceSolrException ex)
|
||||
{
|
||||
log.error(ex.getMessage(), ex);
|
||||
return new ListItemIdentifiersResult(false, list);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.xoai.data;
|
||||
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.Community;
|
||||
|
||||
import com.lyncode.xoai.dataprovider.core.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
public class DSpaceSet extends Set
|
||||
{
|
||||
public static Set newDSpaceCommunitySet(String handle, String name)
|
||||
{
|
||||
return new Set("com_" + handle.replace('/', '_'), name);
|
||||
}
|
||||
|
||||
public static Set newDSpaceCollectionSet(String handle, String name)
|
||||
{
|
||||
return new Set("col_" + handle.replace('/', '_'), name);
|
||||
}
|
||||
|
||||
public DSpaceSet(Community c)
|
||||
{
|
||||
super("com_" + c.getHandle().replace('/', '_'), c.getName());
|
||||
}
|
||||
|
||||
public DSpaceSet(Collection c)
|
||||
{
|
||||
super("col_" + c.getHandle().replace('/', '_'), c.getName());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.xoai.data;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.log4j.LogManager;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.storage.rdbms.DatabaseManager;
|
||||
import org.dspace.storage.rdbms.TableRow;
|
||||
import org.dspace.storage.rdbms.TableRowIterator;
|
||||
|
||||
import com.lyncode.xoai.dataprovider.core.ListSetsResult;
|
||||
import com.lyncode.xoai.dataprovider.core.Set;
|
||||
import com.lyncode.xoai.dataprovider.data.AbstractSetRepository;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.Community;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.handle.HandleManager;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
public class DSpaceSetRepository extends AbstractSetRepository
|
||||
{
|
||||
private static Logger log = LogManager.getLogger(DSpaceSetRepository.class);
|
||||
|
||||
private Context _context;
|
||||
|
||||
public DSpaceSetRepository(Context context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
private int getCommunityCount()
|
||||
{
|
||||
String query = "SELECT COUNT(*) as count FROM community";
|
||||
try
|
||||
{
|
||||
TableRowIterator iterator = DatabaseManager.query(_context, query);
|
||||
if (iterator.hasNext())
|
||||
return (int) iterator.next().getLongColumn("count");
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int getCollectionCount()
|
||||
{
|
||||
String query = "SELECT COUNT(*) as count FROM collection";
|
||||
try
|
||||
{
|
||||
TableRowIterator iterator = DatabaseManager.query(_context, query);
|
||||
if (iterator.hasNext())
|
||||
return (int) iterator.next().getLongColumn("count");
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private List<Set> community(int offset, int length)
|
||||
{
|
||||
List<Set> array = new ArrayList<Set>();
|
||||
String query = "SELECT community_id, name, handle FROM community c, handle h WHERE h.resource_id=community_id AND h.resource_type_id=? ORDER BY community_id";
|
||||
String db = ConfigurationManager.getProperty("db.name");
|
||||
boolean postgres = true;
|
||||
// Assuming postgres as default
|
||||
if ("oracle".equals(db))
|
||||
postgres = false;
|
||||
if (postgres)
|
||||
{
|
||||
query += " OFFSET ? LIMIT ?";
|
||||
}
|
||||
else
|
||||
{
|
||||
// ORACLE
|
||||
query = "SELECT *, ROWNUM r FROM (" + query
|
||||
+ ") WHERE r BETWEEN ? AND ?";
|
||||
length = length + offset;
|
||||
}
|
||||
try
|
||||
{
|
||||
TableRowIterator iterator = DatabaseManager.query(_context, query,
|
||||
Constants.COMMUNITY, offset, length);
|
||||
int i = 0;
|
||||
while (iterator.hasNext() && i < length)
|
||||
{
|
||||
TableRow row = iterator.next();
|
||||
array.add(DSpaceSet.newDSpaceCommunitySet(
|
||||
row.getStringColumn("handle"),
|
||||
row.getStringColumn("name")));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
private List<Set> collection(int offset, int length)
|
||||
{
|
||||
List<Set> array = new ArrayList<Set>();
|
||||
String query = "SELECT collection_id, name, handle FROM collection c, handle h WHERE h.resource_id=collection_id AND h.resource_type_id=? ORDER BY collection_id";
|
||||
String db = ConfigurationManager.getProperty("db.name");
|
||||
boolean postgres = true;
|
||||
// Assuming postgres as default
|
||||
if ("oracle".equals(db))
|
||||
postgres = false;
|
||||
if (postgres)
|
||||
{
|
||||
query += " OFFSET ? LIMIT ?";
|
||||
}
|
||||
else
|
||||
{
|
||||
// ORACLE
|
||||
query = "SELECT *, ROWNUM r FROM (" + query
|
||||
+ ") WHERE r BETWEEN ? AND ?";
|
||||
length = length + offset;
|
||||
}
|
||||
try
|
||||
{
|
||||
TableRowIterator iterator = DatabaseManager.query(_context, query,
|
||||
Constants.COLLECTION, offset, length);
|
||||
int i = 0;
|
||||
while (iterator.hasNext() && i < length)
|
||||
{
|
||||
TableRow row = iterator.next();
|
||||
array.add(DSpaceSet.newDSpaceCollectionSet(
|
||||
row.getStringColumn("handle"),
|
||||
row.getStringColumn("name")));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ListSetsResult retrieveSets(int offset, int length)
|
||||
{
|
||||
// Only database sets (virtual sets are added by lyncode common library)
|
||||
log.debug("Quering sets. Offset: " + offset + " - Length: " + length);
|
||||
List<Set> array = new ArrayList<Set>();
|
||||
int communityCount = this.getCommunityCount();
|
||||
log.debug("Communities: " + communityCount);
|
||||
int collectionCount = this.getCollectionCount();
|
||||
log.debug("Collections: " + collectionCount);
|
||||
|
||||
if (offset < communityCount)
|
||||
{
|
||||
if (offset + length > communityCount)
|
||||
{
|
||||
// Add some collections
|
||||
List<Set> tmp = community(offset, length);
|
||||
array.addAll(tmp);
|
||||
array.addAll(collection(0, length - tmp.size()));
|
||||
}
|
||||
else
|
||||
array.addAll(community(offset, length));
|
||||
}
|
||||
else if (offset < communityCount + collectionCount)
|
||||
{
|
||||
array.addAll(collection(offset - communityCount, length));
|
||||
}
|
||||
log.debug("Has More Results: "
|
||||
+ ((offset + length < communityCount + collectionCount) ? "Yes"
|
||||
: "No"));
|
||||
return new ListSetsResult(offset + length < communityCount
|
||||
+ collectionCount, array, communityCount + collectionCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportSets()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean exists(String setSpec)
|
||||
{
|
||||
if (setSpec.startsWith("col_"))
|
||||
{
|
||||
try
|
||||
{
|
||||
DSpaceObject dso = HandleManager.resolveToObject(_context,
|
||||
setSpec.replace("col_", "").replace("_", "/"));
|
||||
if (dso == null || !(dso instanceof Collection))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.error(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
else if (setSpec.startsWith("com_"))
|
||||
{
|
||||
try
|
||||
{
|
||||
DSpaceObject dso = HandleManager.resolveToObject(_context,
|
||||
setSpec.replace("com_", "").replace("_", "/"));
|
||||
if (dso == null || !(dso instanceof Community))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.error(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.xoai.data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.log4j.LogManager;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.solr.common.SolrDocument;
|
||||
|
||||
import com.lyncode.xoai.dataprovider.core.ItemMetadata;
|
||||
import com.lyncode.xoai.dataprovider.core.ReferenceSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
public class DSpaceSolrItem extends DSpaceItem
|
||||
{
|
||||
private static Logger log = LogManager
|
||||
.getLogger(DSpaceSolrItem.class);
|
||||
|
||||
private String unparsedMD;
|
||||
private ItemMetadata metadata;
|
||||
private String handle;
|
||||
private Date lastMod;
|
||||
private List<ReferenceSet> sets;
|
||||
private boolean deleted;
|
||||
|
||||
public DSpaceSolrItem (SolrDocument doc) {
|
||||
unparsedMD = (String) doc.getFieldValue("item.compile");
|
||||
handle = (String) doc.getFieldValue("item.handle");
|
||||
lastMod = (Date) doc.getFieldValue("item.lastmodified");
|
||||
sets = new ArrayList<ReferenceSet>();
|
||||
for (Object obj : doc.getFieldValues("item.communities"))
|
||||
sets.add(new ReferenceSet((String) obj));
|
||||
for (Object obj : doc.getFieldValues("item.collections"))
|
||||
sets.add(new ReferenceSet((String) obj));
|
||||
deleted = (Boolean) doc.getFieldValue("item.deleted");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemMetadata getMetadata()
|
||||
{
|
||||
if (metadata == null) {
|
||||
metadata = new ItemMetadata(unparsedMD);
|
||||
}
|
||||
return metadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getDatestamp()
|
||||
{
|
||||
return lastMod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ReferenceSet> getSets()
|
||||
{
|
||||
return sets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDeleted()
|
||||
{
|
||||
return deleted;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getHandle()
|
||||
{
|
||||
return handle;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.xoai.exceptions;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class CompilingException extends Exception
|
||||
{
|
||||
|
||||
public CompilingException()
|
||||
{
|
||||
}
|
||||
|
||||
public CompilingException(String arg0)
|
||||
{
|
||||
super(arg0);
|
||||
}
|
||||
|
||||
public CompilingException(Throwable arg0)
|
||||
{
|
||||
super(arg0);
|
||||
}
|
||||
|
||||
public CompilingException(String arg0, Throwable arg1)
|
||||
{
|
||||
super(arg0, arg1);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.xoai.exceptions;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
public class InvalidMetadataFieldException extends Exception
|
||||
{
|
||||
|
||||
private static final long serialVersionUID = 5187555092904394914L;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
|
||||
package org.dspace.xoai.filter;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.log4j.LogManager;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.solr.client.solrj.util.ClientUtils;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.xoai.data.DSpaceDatabaseItem;
|
||||
import org.dspace.xoai.exceptions.InvalidMetadataFieldException;
|
||||
import org.dspace.xoai.filter.data.DSpaceMetadataFilterOperator;
|
||||
import org.dspace.xoai.util.MetadataFieldManager;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
public class DSpaceAtLeastOneMetadataFilter extends DSpaceFilter
|
||||
{
|
||||
private static Logger log = LogManager
|
||||
.getLogger(DSpaceAtLeastOneMetadataFilter.class);
|
||||
|
||||
private String _field;
|
||||
|
||||
private DSpaceMetadataFilterOperator _operator = DSpaceMetadataFilterOperator.UNDEF;
|
||||
|
||||
private List<String> _values;
|
||||
|
||||
private String _value;
|
||||
|
||||
private String getField()
|
||||
{
|
||||
if (_field == null)
|
||||
{
|
||||
_field = super.getParameter("field");
|
||||
}
|
||||
return _field;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private String getValue()
|
||||
{
|
||||
if (_value == null)
|
||||
{
|
||||
_value = super.getParameter("value");
|
||||
}
|
||||
return _value;
|
||||
}
|
||||
|
||||
private List<String> getValues()
|
||||
{
|
||||
if (_values == null)
|
||||
{
|
||||
_values = super.getParameters("value");
|
||||
}
|
||||
return _values;
|
||||
}
|
||||
|
||||
private DSpaceMetadataFilterOperator getOperator()
|
||||
{
|
||||
if (_operator == DSpaceMetadataFilterOperator.UNDEF)
|
||||
{
|
||||
_operator = DSpaceMetadataFilterOperator.valueOf(super
|
||||
.getParameter("operator").toUpperCase());
|
||||
}
|
||||
return _operator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DatabaseFilterResult getWhere(Context context)
|
||||
{
|
||||
if (this.getField() != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
int id = MetadataFieldManager.getFieldID(context,
|
||||
this.getField());
|
||||
return this.getWhere(id, this.getValues());
|
||||
}
|
||||
catch (InvalidMetadataFieldException ex)
|
||||
{
|
||||
log.error(ex.getMessage(), ex);
|
||||
}
|
||||
catch (SQLException ex)
|
||||
{
|
||||
log.error(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
return new DatabaseFilterResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShown(DSpaceDatabaseItem item)
|
||||
{
|
||||
if (this.getField() == null)
|
||||
return true;
|
||||
List<String> values = item.getMetadata(this.getField()+".*");
|
||||
for (String praticalValue : values)
|
||||
{
|
||||
for (String theoreticValue : this.getValues())
|
||||
{
|
||||
switch (this.getOperator())
|
||||
{
|
||||
case CONTAINS:
|
||||
if (praticalValue.contains(theoreticValue))
|
||||
return true;
|
||||
break;
|
||||
case ENDS_WITH:
|
||||
if (praticalValue.endsWith(theoreticValue))
|
||||
return true;
|
||||
break;
|
||||
case EQUAL:
|
||||
if (praticalValue.equals(theoreticValue))
|
||||
return true;
|
||||
break;
|
||||
case GREATER:
|
||||
if (praticalValue.compareTo(theoreticValue) > 0)
|
||||
return true;
|
||||
break;
|
||||
case GREATER_OR_EQUAL:
|
||||
if (praticalValue.compareTo(theoreticValue) >= 0)
|
||||
return true;
|
||||
break;
|
||||
case LOWER:
|
||||
if (praticalValue.compareTo(theoreticValue) < 0)
|
||||
return true;
|
||||
break;
|
||||
case LOWER_OR_EQUAL:
|
||||
if (praticalValue.compareTo(theoreticValue) <= 0)
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private DatabaseFilterResult getWhere(int mdid, List<String> values)
|
||||
{
|
||||
List<String> parts = new ArrayList<String>();
|
||||
List<Object> params = new ArrayList<Object>();
|
||||
params.add(mdid);
|
||||
for (String v : values)
|
||||
this.buildWhere(v, parts, params);
|
||||
if (parts.size() > 0)
|
||||
{
|
||||
String query = "EXISTS (SELECT tmp.* FROM metadatavalue tmp WHERE tmp.item_id=i.item_id AND tmp.metadata_field_id=?"
|
||||
+ " AND ("
|
||||
+ StringUtils.join(parts.iterator(), " OR ")
|
||||
+ "))";
|
||||
return new DatabaseFilterResult(query, params);
|
||||
}
|
||||
return new DatabaseFilterResult();
|
||||
}
|
||||
|
||||
private void buildWhere(String value, List<String> parts,
|
||||
List<Object> params)
|
||||
{
|
||||
switch (this.getOperator())
|
||||
{
|
||||
case CONTAINS:
|
||||
parts.add("(tmp.text_value LIKE ?)");
|
||||
params.add("%" + value + "%");
|
||||
break;
|
||||
case ENDS_WITH:
|
||||
parts.add("(tmp.text_value LIKE ?)");
|
||||
params.add("%" + value);
|
||||
break;
|
||||
case STARTS_WITH:
|
||||
parts.add("(tmp.text_value LIKE ?)");
|
||||
params.add(value + "%");
|
||||
break;
|
||||
case EQUAL:
|
||||
parts.add("(tmp.text_value LIKE ?)");
|
||||
params.add(value);
|
||||
break;
|
||||
case GREATER:
|
||||
parts.add("(tmp.text_value > ?)");
|
||||
params.add(value);
|
||||
break;
|
||||
case LOWER:
|
||||
parts.add("(tmp.text_value < ?)");
|
||||
params.add(value);
|
||||
break;
|
||||
case LOWER_OR_EQUAL:
|
||||
parts.add("(tmp.text_value <= ?)");
|
||||
params.add(value);
|
||||
break;
|
||||
case GREATER_OR_EQUAL:
|
||||
parts.add("(tmp.text_value >= ?)");
|
||||
params.add(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SolrFilterResult getQuery()
|
||||
{
|
||||
String field = this.getField();
|
||||
List<String> parts = new ArrayList<String>();
|
||||
if (this.getField() != null)
|
||||
{
|
||||
for (String v : this.getValues())
|
||||
this.buildQuery("metadata." + field,
|
||||
ClientUtils.escapeQueryChars(v), parts);
|
||||
if (parts.size() > 0)
|
||||
{
|
||||
return new SolrFilterResult(StringUtils.join(parts.iterator(),
|
||||
" OR "));
|
||||
}
|
||||
}
|
||||
return new SolrFilterResult();
|
||||
}
|
||||
|
||||
private void buildQuery(String field, String value, List<String> parts)
|
||||
{
|
||||
switch (this.getOperator())
|
||||
{
|
||||
case CONTAINS:
|
||||
parts.add("(" + field + ":*" + value + "*)");
|
||||
break;
|
||||
case ENDS_WITH:
|
||||
parts.add("(" + field + ":*" + value + ")");
|
||||
break;
|
||||
case STARTS_WITH:
|
||||
parts.add("(" + field + ":" + value + "*)");
|
||||
break;
|
||||
case EQUAL:
|
||||
parts.add("(" + field + ":" + value + ")");
|
||||
break;
|
||||
case GREATER:
|
||||
parts.add("(" + field + ":[" + value + " TO *])");
|
||||
break;
|
||||
case LOWER:
|
||||
parts.add("(" + field + ":[* TO " + value + "])");
|
||||
break;
|
||||
case LOWER_OR_EQUAL:
|
||||
parts.add("(-(" + field + ":[" + value + " TO *]))");
|
||||
break;
|
||||
case GREATER_OR_EQUAL:
|
||||
parts.add("(-(" + field + ":[* TO " + value + "]))");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
|
||||
package org.dspace.xoai.filter;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.apache.log4j.LogManager;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.authorize.AuthorizeManager;
|
||||
import org.dspace.content.Bundle;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.xoai.data.DSpaceDatabaseItem;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
public class DSpaceAuthorizationFilter extends DSpaceFilter
|
||||
{
|
||||
private static Logger log = LogManager
|
||||
.getLogger(DSpaceAuthorizationFilter.class);
|
||||
|
||||
@Override
|
||||
public DatabaseFilterResult getWhere(Context context)
|
||||
{
|
||||
List<Object> params = new ArrayList<Object>();
|
||||
return new DatabaseFilterResult("EXISTS (SELECT p.action_id FROM "
|
||||
+ "resourcepolicy p, " + "bundle2bitstream b, " + "bundle bu, "
|
||||
+ "item2bundle ib " + "WHERE " + "p.resource_type_id=0 AND "
|
||||
+ "p.resource_id=b.bitstream_id AND "
|
||||
+ "p.epersongroup_id=0 AND " + "b.bundle_id=ib.bundle_id AND "
|
||||
+ "bu.bundle_id=b.bundle_id AND " + "bu.name='ORIGINAL' AND "
|
||||
+ "ib.item_id=i.item_id)", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShown(DSpaceDatabaseItem item)
|
||||
{
|
||||
try
|
||||
{
|
||||
Context ctx = super.getContext();
|
||||
Item dsitem = item.getItem();
|
||||
AuthorizeManager.authorizeAction(ctx, dsitem, Constants.READ);
|
||||
for (Bundle b : dsitem.getBundles())
|
||||
AuthorizeManager.authorizeAction(ctx, b, Constants.READ);
|
||||
return true;
|
||||
}
|
||||
catch (AuthorizeException ex)
|
||||
{
|
||||
log.debug(ex.getMessage());
|
||||
}
|
||||
catch (SQLException ex)
|
||||
{
|
||||
log.error(ex.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SolrFilterResult getQuery()
|
||||
{
|
||||
return new SolrFilterResult("item.public:true");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.xoai.filter;
|
||||
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.xoai.data.DSpaceDatabaseItem;
|
||||
|
||||
import com.lyncode.xoai.dataprovider.data.AbstractItemIdentifier;
|
||||
import com.lyncode.xoai.dataprovider.filter.AbstractFilter;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
public abstract class DSpaceFilter extends AbstractFilter
|
||||
{
|
||||
private Context _ctx = null;
|
||||
|
||||
public void initialize(Context ctx)
|
||||
{
|
||||
_ctx = ctx;
|
||||
}
|
||||
|
||||
public Context getContext()
|
||||
{
|
||||
return _ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns null if no where given. Or non empty if some where is given.
|
||||
*
|
||||
* @param context
|
||||
* @param item
|
||||
* @return
|
||||
*/
|
||||
public abstract DatabaseFilterResult getWhere(Context context);
|
||||
|
||||
public abstract SolrFilterResult getQuery();
|
||||
|
||||
public abstract boolean isShown(DSpaceDatabaseItem item);
|
||||
|
||||
@Override
|
||||
public boolean isItemShown(AbstractItemIdentifier item)
|
||||
{
|
||||
if (item instanceof DSpaceDatabaseItem)
|
||||
{
|
||||
return this.isShown((DSpaceDatabaseItem) item);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.xoai.filter;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.apache.log4j.LogManager;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.xoai.data.DSpaceDatabaseItem;
|
||||
import org.dspace.xoai.exceptions.InvalidMetadataFieldException;
|
||||
import org.dspace.xoai.util.MetadataFieldManager;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
public class DSpaceMetadataExistsFilter extends DSpaceFilter
|
||||
{
|
||||
private static Logger log = LogManager
|
||||
.getLogger(DSpaceMetadataExistsFilter.class);
|
||||
|
||||
private String _field;
|
||||
|
||||
private String getField()
|
||||
{
|
||||
if (this._field == null)
|
||||
{
|
||||
_field = super.getParameter("field");
|
||||
}
|
||||
return _field;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DatabaseFilterResult getWhere(Context context)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new DatabaseFilterResult(
|
||||
"EXISTS (SELECT tmp.* FROM metadatavalue tmp WHERE tmp.item_id=i.item_id AND tmp.metadata_field_id=?)",
|
||||
MetadataFieldManager.getFieldID(context, this.getField()));
|
||||
}
|
||||
catch (InvalidMetadataFieldException e)
|
||||
{
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return new DatabaseFilterResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShown(DSpaceDatabaseItem item)
|
||||
{
|
||||
if (item.getMetadata(this.getField()+".*").size() > 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SolrFilterResult getQuery()
|
||||
{
|
||||
return new SolrFilterResult("metadata." + this.getField() + ":[* TO *]");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.xoai.filter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
public class DatabaseFilterResult
|
||||
{
|
||||
private String _where;
|
||||
|
||||
private List<Object> _params;
|
||||
|
||||
private boolean _nothing;
|
||||
|
||||
public DatabaseFilterResult()
|
||||
{
|
||||
_nothing = true;
|
||||
}
|
||||
|
||||
public DatabaseFilterResult(String where, Object... params)
|
||||
{
|
||||
_nothing = false;
|
||||
_where = where;
|
||||
_params = new ArrayList<Object>();
|
||||
for (Object obj : params)
|
||||
_params.add(obj);
|
||||
}
|
||||
|
||||
public DatabaseFilterResult(String where, List<Object> params)
|
||||
{
|
||||
_nothing = false;
|
||||
_where = where;
|
||||
_params = params;
|
||||
}
|
||||
|
||||
public boolean hasResult()
|
||||
{
|
||||
return !_nothing;
|
||||
}
|
||||
|
||||
public String getWhere()
|
||||
{
|
||||
return _where;
|
||||
}
|
||||
|
||||
public List<Object> getParameters()
|
||||
{
|
||||
return _params;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.xoai.filter;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.solr.client.solrj.util.ClientUtils;
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.xoai.data.DSpaceDatabaseItem;
|
||||
import org.dspace.xoai.util.DateUtils;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
public class DateFromFilter extends DSpaceFilter
|
||||
{
|
||||
private Date _date;
|
||||
|
||||
public DateFromFilter(Date date)
|
||||
{
|
||||
_date = date;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DatabaseFilterResult getWhere(Context context)
|
||||
{
|
||||
return new DatabaseFilterResult("i.last_modified >= ?",
|
||||
new java.sql.Date(_date.getTime()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShown(DSpaceDatabaseItem item)
|
||||
{
|
||||
if (item.getDatestamp().compareTo(_date) >= 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private String dateToString(Date date)
|
||||
{
|
||||
return DateUtils.formatToSolr(date);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SolrFilterResult getQuery()
|
||||
{
|
||||
return new SolrFilterResult("item.lastmodified:["
|
||||
+ ClientUtils.escapeQueryChars(this.dateToString(_date))
|
||||
+ " TO *]");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.xoai.filter;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import org.apache.solr.client.solrj.util.ClientUtils;
|
||||
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.xoai.data.DSpaceDatabaseItem;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
public class DateUntilFilter extends DSpaceFilter
|
||||
{
|
||||
private Date _date;
|
||||
|
||||
public DateUntilFilter(Date date)
|
||||
{
|
||||
_date = date;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DatabaseFilterResult getWhere(Context context)
|
||||
{
|
||||
return new DatabaseFilterResult("i.last_modified <= ?",
|
||||
new java.sql.Date(_date.getTime()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShown(DSpaceDatabaseItem item)
|
||||
{
|
||||
if (item.getDatestamp().compareTo(_date) <= 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private String dateToString(Date date)
|
||||
{
|
||||
SimpleDateFormat formatDate = new SimpleDateFormat(
|
||||
"yyyy-MM-dd'T'HH:mm:ss'Z'");
|
||||
return formatDate.format(date);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SolrFilterResult getQuery()
|
||||
{
|
||||
return new SolrFilterResult("item.lastmodified:[* TO "
|
||||
+ ClientUtils.escapeQueryChars(this.dateToString(_date)) + "]");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.xoai.filter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.log4j.LogManager;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.dspace.core.Context;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import org.apache.solr.client.solrj.util.ClientUtils;
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.Community;
|
||||
import org.dspace.content.DSpaceObject;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.handle.HandleManager;
|
||||
import org.dspace.xoai.data.DSpaceDatabaseItem;
|
||||
import org.dspace.xoai.util.XOAIDatabaseManager;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
public class DspaceSetSpecFilter extends DSpaceFilter
|
||||
{
|
||||
private static Logger log = LogManager.getLogger(DspaceSetSpecFilter.class);
|
||||
|
||||
private String _setSpec;
|
||||
|
||||
public DspaceSetSpecFilter(String spec)
|
||||
{
|
||||
_setSpec = spec;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DatabaseFilterResult getWhere(Context context)
|
||||
{
|
||||
if (_setSpec.startsWith("col_"))
|
||||
{
|
||||
try
|
||||
{
|
||||
DSpaceObject dso = HandleManager.resolveToObject(context,
|
||||
_setSpec.replace("col_", ""));
|
||||
return new DatabaseFilterResult(
|
||||
"EXISTS (SELECT tmp.* FROM collection2item tmp WHERE tmp.item_id=i.item_id AND collection_id = ?)",
|
||||
dso.getID());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.error(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
else if (_setSpec.startsWith("com_"))
|
||||
{
|
||||
try
|
||||
{
|
||||
DSpaceObject dso = HandleManager.resolveToObject(context,
|
||||
_setSpec.replace("com_", ""));
|
||||
List<Integer> list = XOAIDatabaseManager.getAllSubCollections(
|
||||
context, dso.getID());
|
||||
String subCollections = StringUtils.join(list.iterator(), ",");
|
||||
return new DatabaseFilterResult(
|
||||
"EXISTS (SELECT tmp.* FROM collection2item tmp WHERE tmp.item_id=i.item_id AND collection_id IN ("
|
||||
+ subCollections + "))");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
return new DatabaseFilterResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShown(DSpaceDatabaseItem item)
|
||||
{
|
||||
try
|
||||
{
|
||||
Item dsitem = item.getItem();
|
||||
if (_setSpec.startsWith("col_"))
|
||||
{
|
||||
String handle = _setSpec.replace("col_", "");
|
||||
for (Collection c : dsitem.getCollections())
|
||||
if (c.getHandle().replace('/', '_').equals(handle))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
else if (_setSpec.startsWith("com_"))
|
||||
{
|
||||
String handle = _setSpec.replace("com_", "");
|
||||
for (Community c : XOAIDatabaseManager
|
||||
.flatParentCommunities(dsitem))
|
||||
if (c.getHandle().replace('/', '_').equals(handle))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (SQLException ex)
|
||||
{
|
||||
log.error(ex.getMessage(), ex);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SolrFilterResult getQuery()
|
||||
{
|
||||
if (_setSpec.startsWith("col_"))
|
||||
{
|
||||
try
|
||||
{
|
||||
return new SolrFilterResult("item.collections:"
|
||||
+ ClientUtils.escapeQueryChars(_setSpec));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.error(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
else if (_setSpec.startsWith("com_"))
|
||||
{
|
||||
try
|
||||
{
|
||||
return new SolrFilterResult("item.communities:"
|
||||
+ ClientUtils.escapeQueryChars(_setSpec));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
return new SolrFilterResult();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.xoai.filter;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
public class SolrFilterResult
|
||||
{
|
||||
|
||||
private String _where;
|
||||
|
||||
private boolean _nothing;
|
||||
|
||||
public SolrFilterResult()
|
||||
{
|
||||
_nothing = true;
|
||||
}
|
||||
|
||||
public SolrFilterResult(String query)
|
||||
{
|
||||
_nothing = false;
|
||||
_where = query;
|
||||
}
|
||||
|
||||
public boolean hasResult()
|
||||
{
|
||||
return !_nothing;
|
||||
}
|
||||
|
||||
public String getQuery()
|
||||
{
|
||||
return _where;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
|
||||
package org.dspace.xoai.filter.data;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
public enum DSpaceMetadataFilterOperator {
|
||||
UNDEF, CONTAINS, EQUAL, GREATER, LOWER, GREATER_OR_EQUAL, LOWER_OR_EQUAL, ENDS_WITH, STARTS_WITH
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
|
||||
package org.dspace.xoai.solr;
|
||||
|
||||
import org.apache.solr.client.solrj.SolrQuery;
|
||||
import org.apache.solr.client.solrj.SolrQuery.ORDER;
|
||||
import org.apache.solr.client.solrj.SolrServer;
|
||||
import org.apache.solr.client.solrj.SolrServerException;
|
||||
import org.apache.solr.client.solrj.response.QueryResponse;
|
||||
import org.apache.solr.common.SolrDocument;
|
||||
import org.apache.solr.common.SolrDocumentList;
|
||||
import org.dspace.xoai.solr.exceptions.DSpaceSolrException;
|
||||
import org.dspace.xoai.solr.exceptions.SolrSearchEmptyException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
public class DSpaceSolrSearch
|
||||
{
|
||||
public static SolrDocumentList query(SolrQuery solrParams)
|
||||
throws DSpaceSolrException
|
||||
{
|
||||
try
|
||||
{
|
||||
SolrServer server = DSpaceSolrServer.getServer();
|
||||
solrParams.addSortField("item.id", ORDER.asc);
|
||||
QueryResponse response = server.query(solrParams);
|
||||
return response.getResults();
|
||||
}
|
||||
catch (SolrServerException ex)
|
||||
{
|
||||
throw new DSpaceSolrException(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static SolrDocument querySingle(SolrQuery solrParams)
|
||||
throws SolrSearchEmptyException
|
||||
{
|
||||
try
|
||||
{
|
||||
SolrServer server = DSpaceSolrServer.getServer();
|
||||
solrParams.addSortField("item.id", ORDER.asc);
|
||||
QueryResponse response = server.query(solrParams);
|
||||
if (response.getResults().getNumFound() > 0)
|
||||
return response.getResults().get(0);
|
||||
else
|
||||
throw new SolrSearchEmptyException();
|
||||
}
|
||||
catch (SolrServerException ex)
|
||||
{
|
||||
throw new SolrSearchEmptyException(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
|
||||
package org.dspace.xoai.solr;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
|
||||
import org.apache.log4j.LogManager;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.solr.client.solrj.SolrServer;
|
||||
import org.apache.solr.client.solrj.SolrServerException;
|
||||
import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
public class DSpaceSolrServer
|
||||
{
|
||||
private static Logger log = LogManager.getLogger(DSpaceSolrServer.class);
|
||||
|
||||
private static SolrServer _server = null;
|
||||
|
||||
public static SolrServer getServer() throws SolrServerException
|
||||
{
|
||||
if (_server == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
_server = new CommonsHttpSolrServer(
|
||||
ConfigurationManager.getProperty("oai", "solr.url"));
|
||||
log.debug("Solr Server Initialized");
|
||||
}
|
||||
catch (MalformedURLException e)
|
||||
{
|
||||
throw new SolrServerException(e);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
return _server;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.xoai.solr.exceptions;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class DSpaceSolrException extends Exception
|
||||
{
|
||||
|
||||
/**
|
||||
* Creates a new instance of <code>DSpaceSolrException</code> without detail
|
||||
* message.
|
||||
*/
|
||||
public DSpaceSolrException()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance of <code>DSpaceSolrException</code> with the
|
||||
* specified detail message.
|
||||
*
|
||||
* @param msg
|
||||
* the detail message.
|
||||
*/
|
||||
public DSpaceSolrException(String msg)
|
||||
{
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public DSpaceSolrException(String msg, Throwable t)
|
||||
{
|
||||
super(msg, t);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
|
||||
package org.dspace.xoai.solr.exceptions;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class DSpaceSolrIndexerException extends Exception
|
||||
{
|
||||
/**
|
||||
* Creates a new instance of <code>DSpaceSolrException</code> without detail
|
||||
* message.
|
||||
*/
|
||||
public DSpaceSolrIndexerException()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance of <code>DSpaceSolrException</code> with the
|
||||
* specified detail message.
|
||||
*
|
||||
* @param msg
|
||||
* the detail message.
|
||||
*/
|
||||
public DSpaceSolrIndexerException(String msg)
|
||||
{
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public DSpaceSolrIndexerException(String msg, Throwable t)
|
||||
{
|
||||
super(msg, t);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
|
||||
package org.dspace.xoai.solr.exceptions;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class SolrSearchEmptyException extends Exception
|
||||
{
|
||||
|
||||
/**
|
||||
* Creates a new instance of <code>SolrSearchEmptyException</code> without
|
||||
* detail message.
|
||||
*/
|
||||
public SolrSearchEmptyException()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance of <code>SolrSearchEmptyException</code> with the
|
||||
* specified detail message.
|
||||
*
|
||||
* @param msg
|
||||
* the detail message.
|
||||
*/
|
||||
public SolrSearchEmptyException(String msg)
|
||||
{
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public SolrSearchEmptyException(String msg, Throwable t)
|
||||
{
|
||||
super(msg, t);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.xoai.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.dspace.content.DCValue;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class DSpaceDataConvert
|
||||
{
|
||||
public static List<String> getValues(DCValue[] values)
|
||||
{
|
||||
List<String> result = new ArrayList<String>();
|
||||
for (DCValue dc : values)
|
||||
result.add(dc.value);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String getValue(DCValue[] values)
|
||||
{
|
||||
if (values.length > 0)
|
||||
return values[0].value;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.xoai.util;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.apache.log4j.LogManager;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
public class DateUtils
|
||||
{
|
||||
|
||||
private static Logger log = LogManager.getLogger(DateUtils.class);
|
||||
|
||||
public static String formatToSolr(Date date)
|
||||
{
|
||||
// 2008-01-01T00:00:00Z
|
||||
SimpleDateFormat format = new SimpleDateFormat(
|
||||
"yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.getDefault());
|
||||
format.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
String ret = format.format(date);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static Date parseDate(String date)
|
||||
{
|
||||
// 2008-01-01T00:00:00Z
|
||||
SimpleDateFormat format = new SimpleDateFormat(
|
||||
"yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.getDefault());
|
||||
// format.setTimeZone(TimeZone.getTimeZone("ZULU"));
|
||||
Date ret;
|
||||
try
|
||||
{
|
||||
ret = format.parse(date);
|
||||
return ret;
|
||||
}
|
||||
catch (ParseException e)
|
||||
{
|
||||
format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",
|
||||
Locale.getDefault());
|
||||
try
|
||||
{
|
||||
return format.parse(date);
|
||||
}
|
||||
catch (ParseException e1)
|
||||
{
|
||||
format = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
|
||||
try
|
||||
{
|
||||
return format.parse(date);
|
||||
}
|
||||
catch (ParseException e2)
|
||||
{
|
||||
format = new SimpleDateFormat("yyyy-MM",
|
||||
Locale.getDefault());
|
||||
try
|
||||
{
|
||||
return format.parse(date);
|
||||
}
|
||||
catch (ParseException e3)
|
||||
{
|
||||
format = new SimpleDateFormat("yyyy",
|
||||
Locale.getDefault());
|
||||
try
|
||||
{
|
||||
return format.parse(date);
|
||||
}
|
||||
catch (ParseException e4)
|
||||
{
|
||||
log.error(e4.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new Date();
|
||||
}
|
||||
|
||||
public static Date parseFromSolrDate(String date)
|
||||
{
|
||||
// 2008-01-01T00:00:00Z
|
||||
SimpleDateFormat format = new SimpleDateFormat(
|
||||
"yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.getDefault());
|
||||
// format.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
Date ret;
|
||||
try
|
||||
{
|
||||
ret = format.parse(date);
|
||||
return ret;
|
||||
}
|
||||
catch (ParseException e)
|
||||
{
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return new Date();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.xoai.util;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.log4j.LogManager;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.dspace.authorize.AuthorizeException;
|
||||
import org.dspace.content.Bitstream;
|
||||
import org.dspace.content.Bundle;
|
||||
import org.dspace.content.DCValue;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.content.authority.Choices;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
import org.dspace.core.Constants;
|
||||
import org.dspace.core.Utils;
|
||||
import org.dspace.xoai.data.DSpaceDatabaseItem;
|
||||
|
||||
import com.lyncode.xoai.dataprovider.util.Base64Utils;
|
||||
import com.lyncode.xoai.dataprovider.xml.xoai.Element;
|
||||
import com.lyncode.xoai.dataprovider.xml.xoai.Metadata;
|
||||
import com.lyncode.xoai.dataprovider.xml.xoai.ObjectFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class ItemUtils
|
||||
{
|
||||
private static Logger log = LogManager
|
||||
.getLogger(ItemUtils.class);
|
||||
|
||||
private static Element getElement(List<Element> list, String name)
|
||||
{
|
||||
for (Element e : list)
|
||||
if (name.equals(e.getName()))
|
||||
return e;
|
||||
|
||||
return null;
|
||||
}
|
||||
private static Element create(ObjectFactory factory, String name)
|
||||
{
|
||||
Element e = factory.createElement();
|
||||
e.setName(name);
|
||||
return e;
|
||||
}
|
||||
|
||||
private static Element.Field createValue(ObjectFactory factory, String value)
|
||||
{
|
||||
Element.Field e = factory.createElementField();
|
||||
e.setValue(value);
|
||||
return e;
|
||||
}
|
||||
|
||||
private static Element.Field createValue(ObjectFactory factory,
|
||||
String name, String value)
|
||||
{
|
||||
Element.Field e = factory.createElementField();
|
||||
e.setValue(value);
|
||||
e.setName(name);
|
||||
return e;
|
||||
}
|
||||
public static Metadata retrieveMetadata (Item item) {
|
||||
Metadata metadata;
|
||||
|
||||
DSpaceDatabaseItem dspaceItem = new DSpaceDatabaseItem(item);
|
||||
|
||||
// read all metadata into Metadata Object
|
||||
ObjectFactory factory = new ObjectFactory();
|
||||
metadata = factory.createMetadata();
|
||||
DCValue[] vals = item.getMetadata(Item.ANY, Item.ANY, Item.ANY, Item.ANY);
|
||||
for (DCValue val : vals)
|
||||
{
|
||||
Element valueElem = null;
|
||||
Element schema = getElement(metadata.getElement(), val.schema);
|
||||
if (schema == null)
|
||||
{
|
||||
schema = create(factory, val.schema);
|
||||
metadata.getElement().add(schema);
|
||||
}
|
||||
valueElem = schema;
|
||||
|
||||
// Has element.. with XOAI one could have only schema and value
|
||||
if (val.element != null && !val.element.equals(""))
|
||||
{
|
||||
Element element = getElement(schema.getElement(),
|
||||
val.element);
|
||||
if (element == null)
|
||||
{
|
||||
element = create(factory, val.element);
|
||||
schema.getElement().add(element);
|
||||
}
|
||||
valueElem = element;
|
||||
|
||||
// Qualified element?
|
||||
if (val.qualifier != null && !val.qualifier.equals(""))
|
||||
{
|
||||
Element qualifier = getElement(element.getElement(),
|
||||
val.qualifier);
|
||||
if (qualifier == null)
|
||||
{
|
||||
qualifier = create(factory, val.qualifier);
|
||||
element.getElement().add(qualifier);
|
||||
}
|
||||
valueElem = qualifier;
|
||||
}
|
||||
}
|
||||
|
||||
// Language?
|
||||
if (val.language != null && !val.language.equals(""))
|
||||
{
|
||||
Element language = getElement(valueElem.getElement(),
|
||||
val.language);
|
||||
if (language == null)
|
||||
{
|
||||
language = create(factory, val.language);
|
||||
valueElem.getElement().add(language);
|
||||
}
|
||||
valueElem = language;
|
||||
}
|
||||
else
|
||||
{
|
||||
Element language = getElement(valueElem.getElement(),
|
||||
"none");
|
||||
if (language == null)
|
||||
{
|
||||
language = create(factory, "none");
|
||||
valueElem.getElement().add(language);
|
||||
}
|
||||
valueElem = language;
|
||||
}
|
||||
|
||||
valueElem.getField().add(createValue(factory, "value", val.value));
|
||||
if (val.authority != null) {
|
||||
valueElem.getField().add(createValue(factory, "authority", val.authority));
|
||||
if (val.confidence != Choices.CF_NOVALUE)
|
||||
valueElem.getField().add(createValue(factory, "confidence", val.confidence + ""));
|
||||
}
|
||||
}
|
||||
// Done! Metadata has been read!
|
||||
// Now adding bitstream info
|
||||
Element bundles = create(factory, "bundles");
|
||||
metadata.getElement().add(bundles);
|
||||
|
||||
Bundle[] bs;
|
||||
try
|
||||
{
|
||||
bs = item.getBundles();
|
||||
for (Bundle b : bs)
|
||||
{
|
||||
Element bundle = create(factory, "bundle");
|
||||
bundles.getElement().add(bundle);
|
||||
bundle.getField()
|
||||
.add(createValue(factory, "name", b.getName()));
|
||||
|
||||
Element bitstreams = create(factory, "bitstreams");
|
||||
bundle.getElement().add(bitstreams);
|
||||
Bitstream[] bits = b.getBitstreams();
|
||||
for (Bitstream bit : bits)
|
||||
{
|
||||
Element bitstream = create(factory, "bitstream");
|
||||
bitstreams.getElement().add(bitstream);
|
||||
String url = "";
|
||||
String bsName = bitstream.getName();
|
||||
String sid = String.valueOf(bit.getSequenceID());
|
||||
String baseUrl = ConfigurationManager.getProperty("oai",
|
||||
"bitstream.baseUrl");
|
||||
String handle = null;
|
||||
// get handle of parent Item of this bitstream, if there
|
||||
// is one:
|
||||
Bundle[] bn = bit.getBundles();
|
||||
if (bn.length > 0)
|
||||
{
|
||||
Item bi[] = bn[0].getItems();
|
||||
if (bi.length > 0)
|
||||
{
|
||||
handle = bi[0].getHandle();
|
||||
}
|
||||
}
|
||||
if (bsName == null)
|
||||
{
|
||||
String ext[] = bit.getFormat().getExtensions();
|
||||
bsName = "bitstream_" + sid
|
||||
+ (ext.length > 0 ? ext[0] : "");
|
||||
}
|
||||
if (handle != null && baseUrl != null)
|
||||
{
|
||||
url = baseUrl + "/bitstream/"
|
||||
+ URLUtils.encode(handle) + "/"
|
||||
+ sid + "/"
|
||||
+ URLUtils.encode(bsName);
|
||||
}
|
||||
else
|
||||
{
|
||||
url = URLUtils.encode(bsName);
|
||||
}
|
||||
|
||||
String cks = bit.getChecksum();
|
||||
String cka = bit.getChecksumAlgorithm();
|
||||
String oname = bit.getSource();
|
||||
String name = bit.getName();
|
||||
|
||||
if (name != null)
|
||||
bitstream.getField().add(
|
||||
createValue(factory, "name", name));
|
||||
if (oname != null)
|
||||
bitstream.getField().add(
|
||||
createValue(factory, "originalName", name));
|
||||
bitstream.getField().add(
|
||||
createValue(factory, "format", bit.getFormat()
|
||||
.getMIMEType()));
|
||||
bitstream.getField().add(
|
||||
createValue(factory, "size", "" + bit.getSize()));
|
||||
bitstream.getField().add(createValue(factory, "url", url));
|
||||
bitstream.getField().add(
|
||||
createValue(factory, "checksum", cks));
|
||||
bitstream.getField().add(
|
||||
createValue(factory, "checksumAlgorithm", cka));
|
||||
bitstream.getField().add(
|
||||
createValue(factory, "sid", bit.getSequenceID()
|
||||
+ ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SQLException e1)
|
||||
{
|
||||
e1.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
// Other info
|
||||
Element other = create(factory, "others");
|
||||
|
||||
other.getField().add(
|
||||
createValue(factory, "handle", item.getHandle()));
|
||||
other.getField().add(
|
||||
createValue(factory, "identifier", dspaceItem.getIdentifier()));
|
||||
other.getField().add(
|
||||
createValue(factory, "lastModifyDate", item
|
||||
.getLastModified().toString()));
|
||||
metadata.getElement().add(other);
|
||||
|
||||
// Repository Info
|
||||
Element repository = create(factory, "repository");
|
||||
repository.getField().add(
|
||||
createValue(factory, "name",
|
||||
ConfigurationManager.getProperty("dspace.name")));
|
||||
repository.getField().add(
|
||||
createValue(factory, "mail",
|
||||
ConfigurationManager.getProperty("mail.admin")));
|
||||
metadata.getElement().add(repository);
|
||||
|
||||
// Licensing info
|
||||
Element license = create(factory, "license");
|
||||
Bundle[] licBundles;
|
||||
try
|
||||
{
|
||||
licBundles = item.getBundles(Constants.LICENSE_BUNDLE_NAME);
|
||||
if (licBundles.length > 0)
|
||||
{
|
||||
Bundle licBundle = licBundles[0];
|
||||
Bitstream[] licBits = licBundle.getBitstreams();
|
||||
if (licBits.length > 0)
|
||||
{
|
||||
Bitstream licBit = licBits[0];
|
||||
InputStream in;
|
||||
try
|
||||
{
|
||||
in = licBit.retrieve();
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
Utils.bufferedCopy(in, out);
|
||||
license.getField().add(
|
||||
createValue(factory, "bin",
|
||||
Base64Utils.encode(out.toString())));
|
||||
metadata.getElement().add(license);
|
||||
}
|
||||
catch (AuthorizeException e)
|
||||
{
|
||||
log.warn(e.getMessage(), e);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.warn(e.getMessage(), e);
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
log.warn(e.getMessage(), e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SQLException e1)
|
||||
{
|
||||
log.warn(e1.getMessage(), e1);
|
||||
}
|
||||
|
||||
return metadata;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.xoai.util;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.dspace.core.Context;
|
||||
import org.dspace.storage.rdbms.DatabaseManager;
|
||||
import org.dspace.storage.rdbms.TableRowIterator;
|
||||
import org.dspace.xoai.exceptions.InvalidMetadataFieldException;
|
||||
|
||||
import org.apache.log4j.LogManager;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
public class MetadataFieldManager
|
||||
{
|
||||
private static Logger log = LogManager
|
||||
.getLogger(MetadataFieldManager.class);
|
||||
|
||||
private static MetadataFieldManager _manager = null;
|
||||
|
||||
public static int getFieldID(Context context, String field)
|
||||
throws InvalidMetadataFieldException, SQLException
|
||||
{
|
||||
if (_manager == null)
|
||||
_manager = new MetadataFieldManager();
|
||||
if (!_manager.hasField(field))
|
||||
{
|
||||
String[] pieces = field.split(Pattern.quote("."));
|
||||
if (pieces.length > 1)
|
||||
{
|
||||
String schema = pieces[0];
|
||||
String element = pieces[1];
|
||||
String qualifier = null;
|
||||
if (pieces.length > 2)
|
||||
qualifier = pieces[2];
|
||||
String query = "SELECT mfr.metadata_field_id as mid FROM metadatafieldregistry mfr, "
|
||||
+ "metadataschemaregistry msr WHERE mfr.metadata_schema_id=mfr.metadata_schema_id AND "
|
||||
+ "msr.short_id = ? AND mfr.element = ?";
|
||||
|
||||
TableRowIterator iterator;
|
||||
|
||||
if (qualifier == null)
|
||||
{
|
||||
query += " AND mfr.qualifier is NULL";
|
||||
log.debug("Query: " + query);
|
||||
iterator = DatabaseManager.query(context, query, schema,
|
||||
element);
|
||||
}
|
||||
else
|
||||
{
|
||||
log.debug("Qualifier: " + qualifier);
|
||||
query += " AND mfr.qualifier = ?";
|
||||
log.debug("Query: " + query);
|
||||
iterator = DatabaseManager.query(context, query, schema,
|
||||
element, qualifier);
|
||||
}
|
||||
|
||||
if (iterator.hasNext())
|
||||
{
|
||||
_manager.add(field, iterator.next().getIntColumn("mid"));
|
||||
}
|
||||
else
|
||||
throw new InvalidMetadataFieldException();
|
||||
|
||||
}
|
||||
else
|
||||
throw new InvalidMetadataFieldException();
|
||||
}
|
||||
return _manager.getField(field);
|
||||
}
|
||||
|
||||
private Map<String, Integer> _map;
|
||||
|
||||
private MetadataFieldManager()
|
||||
{
|
||||
_map = new HashMap<String, Integer>();
|
||||
}
|
||||
|
||||
public boolean hasField(String field)
|
||||
{
|
||||
return _map.containsKey(field);
|
||||
}
|
||||
|
||||
public int getField(String field)
|
||||
{
|
||||
return _map.get(field).intValue();
|
||||
}
|
||||
|
||||
public void add(String field, int id)
|
||||
{
|
||||
_map.put(field, new Integer(id));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.xoai.util;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
import org.apache.log4j.LogManager;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
public class URLUtils
|
||||
{
|
||||
private static Logger log = LogManager
|
||||
.getLogger(URLUtils.class);
|
||||
public static String encode (String value) {
|
||||
try
|
||||
{
|
||||
return URLEncoder.encode(value, "UTF-8");
|
||||
}
|
||||
catch (UnsupportedEncodingException e)
|
||||
{
|
||||
log.warn(e.getMessage(), e);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,367 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.xoai.util;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.log4j.LogManager;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.core.ConfigurationManager;
|
||||
import org.dspace.core.Utils;
|
||||
import org.dspace.xoai.data.DSpaceDatabaseItem;
|
||||
|
||||
import com.lyncode.xoai.dataprovider.OAIDataProvider;
|
||||
import com.lyncode.xoai.dataprovider.OAIRequestParameters;
|
||||
import com.lyncode.xoai.dataprovider.core.XOAIManager;
|
||||
import com.lyncode.xoai.dataprovider.exceptions.MetadataBindException;
|
||||
import com.lyncode.xoai.dataprovider.exceptions.OAIException;
|
||||
import com.lyncode.xoai.dataprovider.util.Base64Utils;
|
||||
import com.lyncode.xoai.dataprovider.util.MarshallingUtils;
|
||||
import com.lyncode.xoai.dataprovider.xml.xoai.Metadata;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
public class XOAICacheManager
|
||||
{
|
||||
private static Logger log = LogManager.getLogger(XOAICacheManager.class);
|
||||
|
||||
private static final String ITEMDIR = File.separator + "items";
|
||||
|
||||
private static final String REQUESTDIR = File.separator + "requests";
|
||||
|
||||
private static final String DATEFILE = File.separator + "date.file";
|
||||
|
||||
private static String baseDir = null;
|
||||
|
||||
private static String getBaseDir()
|
||||
{
|
||||
if (baseDir == null)
|
||||
{
|
||||
String dir = ConfigurationManager.getProperty("oai", "cache.dir");
|
||||
baseDir = dir;
|
||||
}
|
||||
return baseDir;
|
||||
}
|
||||
|
||||
private static File getCachedResponseFile(String id)
|
||||
{
|
||||
File dir = new File(getBaseDir() + REQUESTDIR);
|
||||
if (!dir.exists())
|
||||
dir.mkdirs();
|
||||
|
||||
String name = File.separator + Base64Utils.encode(id);
|
||||
return new File(getBaseDir() + REQUESTDIR + name);
|
||||
}
|
||||
|
||||
private static File getMetadataCache(Item item)
|
||||
{
|
||||
File dir = new File(getBaseDir() + ITEMDIR);
|
||||
if (!dir.exists())
|
||||
dir.mkdirs();
|
||||
|
||||
String name = File.separator + item.getHandle().replace('/', '_');
|
||||
return new File(getBaseDir() + ITEMDIR + name);
|
||||
}
|
||||
|
||||
public static void compileItem(DSpaceDatabaseItem item)
|
||||
{
|
||||
File metadataCache = getMetadataCache(item.getItem());
|
||||
if (metadataCache.exists())
|
||||
metadataCache.delete();
|
||||
getMetadata(item);
|
||||
}
|
||||
|
||||
public static String getCompiledMetadata(DSpaceDatabaseItem item)
|
||||
throws MetadataBindException
|
||||
{
|
||||
log.debug("Trying to find compiled item");
|
||||
File metadataCache = getMetadataCache(item.getItem());
|
||||
Metadata metadata;
|
||||
String compiled;
|
||||
if (!metadataCache.exists())
|
||||
{
|
||||
log.debug("This is not a compiled item");
|
||||
// generate cache
|
||||
metadata = ItemUtils.retrieveMetadata(item.getItem());
|
||||
FileOutputStream output;
|
||||
try
|
||||
{
|
||||
output = new FileOutputStream(metadataCache);
|
||||
MarshallingUtils.writeMetadata(output, metadata);
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
log.warn(
|
||||
"Could not open file for writing: "
|
||||
+ metadataCache.getPath(), e);
|
||||
}
|
||||
catch (MetadataBindException e)
|
||||
{
|
||||
log.warn("Unable to export in-memory metadata into file: "
|
||||
+ metadataCache.getPath(), e);
|
||||
}
|
||||
}
|
||||
log.debug("This is a compiled item!");
|
||||
// Read compiled file
|
||||
FileInputStream input;
|
||||
try
|
||||
{
|
||||
input = new FileInputStream(metadataCache);
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
Utils.bufferedCopy(input, output);
|
||||
input.close();
|
||||
output.close();
|
||||
compiled = output.toString();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
log.warn(e.getMessage(), e);
|
||||
MarshallingUtils.writeMetadata(output,
|
||||
ItemUtils.retrieveMetadata(item.getItem()));
|
||||
compiled = output.toString();
|
||||
}
|
||||
return compiled;
|
||||
}
|
||||
|
||||
public static Metadata getMetadata(DSpaceDatabaseItem item)
|
||||
{
|
||||
log.debug("Trying to find compiled item");
|
||||
File metadataCache = getMetadataCache(item.getItem());
|
||||
Metadata metadata;
|
||||
if (!metadataCache.exists())
|
||||
{
|
||||
log.debug("This is not a compiled item");
|
||||
// generate cache
|
||||
metadata = ItemUtils.retrieveMetadata(item.getItem());
|
||||
FileOutputStream output;
|
||||
try
|
||||
{
|
||||
output = new FileOutputStream(metadataCache);
|
||||
MarshallingUtils.writeMetadata(output, metadata);
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
log.warn(
|
||||
"Could not open file for writing: "
|
||||
+ metadataCache.getPath(), e);
|
||||
}
|
||||
catch (MetadataBindException e)
|
||||
{
|
||||
log.warn("Unable to export in-memory metadata into file: "
|
||||
+ metadataCache.getPath(), e);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
log.debug("This is a compiled item!");
|
||||
// Read compiled file
|
||||
FileInputStream input;
|
||||
try
|
||||
{
|
||||
input = new FileInputStream(metadataCache);
|
||||
metadata = MarshallingUtils.readMetadata(input);
|
||||
input.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.warn(e.getMessage(), e);
|
||||
metadata = ItemUtils.retrieveMetadata(item.getItem());
|
||||
}
|
||||
}
|
||||
return metadata;
|
||||
}
|
||||
|
||||
private static String getStaticHead()
|
||||
{
|
||||
return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
|
||||
+ ((XOAIManager.getManager().hasStyleSheet()) ? ("<?xml-stylesheet type=\"text/xsl\" href=\""
|
||||
+ XOAIManager.getManager().getStyleSheet() + "\"?>")
|
||||
: "")
|
||||
+ "<OAI-PMH xmlns=\"http://www.openarchives.org/OAI/2.0/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
|
||||
+ "xsi:schemaLocation=\"http://www.openarchives.org/OAI/2.0/ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd\">";
|
||||
}
|
||||
|
||||
public static void handle(String identification,
|
||||
OAIDataProvider dataProvider, OAIRequestParameters parameters,
|
||||
OutputStream out) throws IOException
|
||||
{
|
||||
|
||||
boolean caching = ConfigurationManager.getBooleanProperty("oai", "cache.enabled", true);
|
||||
File cachedResponse = getCachedResponseFile(identification);
|
||||
if (!caching || !cachedResponse.exists())
|
||||
{
|
||||
log.debug("[XOAI] Result not cached");
|
||||
try
|
||||
{
|
||||
// XOAI response facade
|
||||
// This in-memory buffer will be used to store the XOAI response
|
||||
ByteArrayOutputStream intermediate = new ByteArrayOutputStream();
|
||||
dataProvider.handle(parameters, intermediate);
|
||||
String xoaiResponse = intermediate.toString();
|
||||
|
||||
// Cutting the header (to allow one to change the response time)
|
||||
String end = "</responseDate>";
|
||||
int pos = xoaiResponse.indexOf(end);
|
||||
if (pos > 0)
|
||||
xoaiResponse = xoaiResponse.substring(pos + (end.length()));
|
||||
|
||||
// Storing in a file
|
||||
FileOutputStream output = new FileOutputStream(cachedResponse);
|
||||
output.write(xoaiResponse.getBytes());
|
||||
output.flush();
|
||||
output.close();
|
||||
}
|
||||
catch (OAIException e)
|
||||
{
|
||||
// try to remove the file (If an error occurs, it must not show
|
||||
// empty pages)
|
||||
if (cachedResponse.exists())
|
||||
cachedResponse.delete();
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
else
|
||||
log.debug("[OAI 2.0] Cached Result");
|
||||
|
||||
// The cached file is written, now one start by adding the header
|
||||
SimpleDateFormat format = new SimpleDateFormat(
|
||||
"yyyy-MM-dd'T'HH:mm:ss'Z'");
|
||||
out.write((getStaticHead() + "<responseDate>"
|
||||
+ format.format(new Date()) + "</responseDate>").getBytes());
|
||||
|
||||
// Now just simply copy the compiled file
|
||||
FileInputStream in = new FileInputStream(cachedResponse);
|
||||
byte[] buf = new byte[1024];
|
||||
int len;
|
||||
while ((len = in.read(buf)) > 0)
|
||||
{
|
||||
out.write(buf, 0, len);
|
||||
}
|
||||
in.close();
|
||||
}
|
||||
|
||||
private static final SimpleDateFormat format = new SimpleDateFormat();
|
||||
|
||||
public static Date getLastCompilationDate()
|
||||
{
|
||||
FileInputStream fstream;
|
||||
|
||||
try
|
||||
{
|
||||
fstream = new FileInputStream(getBaseDir() + DATEFILE);
|
||||
// Get the object of DataInputStream
|
||||
DataInputStream in = new DataInputStream(fstream);
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(in));
|
||||
try
|
||||
{
|
||||
Date d = format.parse(br.readLine());
|
||||
return d;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.debug(e.getMessage(), e);
|
||||
try
|
||||
{
|
||||
fstream.close();
|
||||
return null;
|
||||
}
|
||||
catch (Exception e1)
|
||||
{
|
||||
log.debug(e1.getMessage(), e1);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
log.debug(e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String... args)
|
||||
{
|
||||
FileOutputStream fstream;
|
||||
try
|
||||
{
|
||||
fstream = new FileOutputStream("test");
|
||||
// Get the object of DataInputStream
|
||||
fstream.write(format.format(new Date()).getBytes());
|
||||
fstream.flush();
|
||||
fstream.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.out.println(format.format(new Date()));
|
||||
}
|
||||
|
||||
public static void setLastCompilationDate(Date date)
|
||||
{
|
||||
FileOutputStream fstream;
|
||||
try
|
||||
{
|
||||
fstream = new FileOutputStream(getBaseDir() + DATEFILE);
|
||||
// Get the object of DataInputStream
|
||||
fstream.write(format.format(date).getBytes());
|
||||
fstream.flush();
|
||||
fstream.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.debug("Error writing the date");
|
||||
}
|
||||
}
|
||||
|
||||
public static void deleteCachedResponses()
|
||||
{
|
||||
File directory = new File(getBaseDir() + REQUESTDIR);
|
||||
if (directory.exists())
|
||||
{
|
||||
// Get all files in directory
|
||||
File[] files = directory.listFiles();
|
||||
for (File file : files)
|
||||
{
|
||||
// Delete each file
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void deleteCompiledItems()
|
||||
{
|
||||
(new File(getBaseDir() + DATEFILE)).delete();
|
||||
File directory = new File(getBaseDir() + ITEMDIR);
|
||||
if (directory.exists())
|
||||
{
|
||||
// Get all files in directory
|
||||
File[] files = directory.listFiles();
|
||||
for (File file : files)
|
||||
{
|
||||
// Delete each file
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* The contents of this file are subject to the license and copyright
|
||||
* detailed in the LICENSE and NOTICE files at the root of the source
|
||||
* tree and available online at
|
||||
*
|
||||
* http://www.dspace.org/license/
|
||||
*/
|
||||
package org.dspace.xoai.util;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
|
||||
import org.dspace.content.Collection;
|
||||
import org.dspace.content.Community;
|
||||
import org.dspace.content.Item;
|
||||
import org.dspace.core.Context;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Lyncode Development Team <dspace@lyncode.com>
|
||||
*/
|
||||
public class XOAIDatabaseManager
|
||||
{
|
||||
public static List<Integer> getAllSubCollections(Context ct, int i)
|
||||
throws SQLException
|
||||
{
|
||||
Queue<Community> comqueue = new LinkedList<Community>();
|
||||
List<Integer> list = new ArrayList<Integer>();
|
||||
comqueue.add(Community.find(ct, i));
|
||||
while (!comqueue.isEmpty())
|
||||
{
|
||||
Community c = comqueue.poll();
|
||||
for (Community sub : c.getSubcommunities())
|
||||
comqueue.add(sub);
|
||||
for (Collection col : c.getCollections())
|
||||
if (!list.contains(col))
|
||||
list.add(col.getID());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static List<Community> flatParentCommunities(Collection c)
|
||||
throws SQLException
|
||||
{
|
||||
Queue<Community> queue = new LinkedList<Community>();
|
||||
List<Community> result = new ArrayList<Community>();
|
||||
for (Community com : c.getCommunities())
|
||||
queue.add(com);
|
||||
|
||||
while (!queue.isEmpty())
|
||||
{
|
||||
Community p = queue.poll();
|
||||
Community par = p.getParentCommunity();
|
||||
if (par != null)
|
||||
queue.add(par);
|
||||
if (!result.contains(p))
|
||||
result.add(p);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<Community> flatParentCommunities(Community c)
|
||||
throws SQLException
|
||||
{
|
||||
Queue<Community> queue = new LinkedList<Community>();
|
||||
List<Community> result = new ArrayList<Community>();
|
||||
|
||||
queue.add(c);
|
||||
|
||||
while (!queue.isEmpty())
|
||||
{
|
||||
Community p = queue.poll();
|
||||
Community par = p.getParentCommunity();
|
||||
if (par != null)
|
||||
queue.add(par);
|
||||
if (!result.contains(p))
|
||||
result.add(p);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<Community> flatParentCommunities(Item c)
|
||||
throws SQLException
|
||||
{
|
||||
Queue<Community> queue = new LinkedList<Community>();
|
||||
List<Community> result = new ArrayList<Community>();
|
||||
|
||||
for (Community com : c.getCommunities())
|
||||
queue.add(com);
|
||||
|
||||
while (!queue.isEmpty())
|
||||
{
|
||||
Community p = queue.poll();
|
||||
Community par = p.getParentCommunity();
|
||||
if (par != null)
|
||||
queue.add(par);
|
||||
if (!result.contains(p))
|
||||
result.add(p);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,115 +1,108 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-oai-webapp</artifactId>
|
||||
<packaging>war</packaging>
|
||||
<name>DSpace OAI :: Web Application Resources</name>
|
||||
<description>DSpace OAI Service Provider Webapplication Resources</description>
|
||||
<?xml version="1.0"?>
|
||||
<project
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<!--
|
||||
A Parent POM that Maven inherits DSpace Default
|
||||
POM atrributes from.
|
||||
-->
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-oai</artifactId>
|
||||
<version>3.0-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
<filters>
|
||||
<filter>${basedir}/../../${filters.file}</filter>
|
||||
</filters>
|
||||
<resources>
|
||||
<!-- Enumerate filtered files explicitly to avoid issues with other config tech. -->
|
||||
<resource>
|
||||
<directory>${basedir}</directory>
|
||||
<filtering>true</filtering>
|
||||
<includes>
|
||||
<include>src/main/webapp/WEB-INF/web.xml</include>
|
||||
</includes>
|
||||
</resource>
|
||||
<!-- Declare a mutually exclusive resource set for non-filtered files. -->
|
||||
<resource>
|
||||
<directory>${basedir}</directory>
|
||||
<filtering>false</filtering>
|
||||
<excludes>
|
||||
<exclude>src/main/webapp/WEB-INF/web.xml</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<configuration>
|
||||
<archiveClasses>false</archiveClasses>
|
||||
<!-- In version 2.1-alpha-1, this was incorrectly named warSourceExcludes -->
|
||||
<packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes>
|
||||
<warSourceExcludes>WEB-INF/lib/*.jar</warSourceExcludes>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>prepare-package</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.mycila.maven-license-plugin</groupId>
|
||||
<artifactId>maven-license-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>**/*.LICENSE</exclude>
|
||||
<exclude>src/main/webapp/oai2.xsl</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<parent>
|
||||
<artifactId>dspace-oai</artifactId>
|
||||
<groupId>org.dspace</groupId>
|
||||
<version>3.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>oracle-support</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>db.name</name>
|
||||
<value>oracle</value>
|
||||
</property>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.oracle</groupId>
|
||||
<artifactId>ojdbc6</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>postgres-support</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>!db.name</name>
|
||||
</property>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
</profiles>
|
||||
<artifactId>dspace-oai-webapp</artifactId>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-oai-api</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<name>DSpace OAI 2.0 :: Web Application Resources</name>
|
||||
<description>Webapp</description>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<configuration>
|
||||
<archiveClasses>false</archiveClasses>
|
||||
<!-- In version 2.1-alpha-1, this was incorrectly named warSourceExcludes -->
|
||||
<packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes>
|
||||
<warSourceExcludes>WEB-INF/lib/*.jar</warSourceExcludes>
|
||||
<webResources>
|
||||
<resource>
|
||||
<filtering>true</filtering>
|
||||
<directory>${basedir}/src/main/webapp</directory>
|
||||
<includes>
|
||||
<include>WEB-INF/web.xml</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</webResources>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>prepare-package</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<activation>
|
||||
<property>
|
||||
<name>dspace.config</name>
|
||||
</property>
|
||||
</activation>
|
||||
<build>
|
||||
<filters>
|
||||
<filter>${dspace.config}</filter>
|
||||
</filters>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>oracle-support</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>db.name</name>
|
||||
<value>oracle</value>
|
||||
</property>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.oracle</groupId>
|
||||
<artifactId>ojdbc6</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>postgres-support</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>!db.name</name>
|
||||
</property>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-oai-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<name>DSpace @ Lyncode</name>
|
||||
<email>dspace@lyncode.com</email>
|
||||
<organization>Lyncode</organization>
|
||||
<organizationUrl>http://www.lyncode.com</organizationUrl>
|
||||
</developer>
|
||||
</developers>
|
||||
</project>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
|
||||
The contents of this file are subject to the license and copyright
|
||||
@@ -8,67 +8,47 @@
|
||||
http://www.dspace.org/license/
|
||||
|
||||
-->
|
||||
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
|
||||
<web-app id="XOAILynCode" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
|
||||
|
||||
<display-name>XOAI Data Provider</display-name>
|
||||
|
||||
<context-param>
|
||||
<description>
|
||||
The location of the main DSpace configuration file
|
||||
</description>
|
||||
<param-name>dspace-config</param-name>
|
||||
<param-value>${dspace.dir}/config/dspace.cfg</param-value>
|
||||
</context-param>
|
||||
|
||||
<context-param>
|
||||
<description>
|
||||
The location of the main DSpace configuration file
|
||||
</description>
|
||||
<param-name>dspace.dir</param-name>
|
||||
<param-value>${dspace.dir}</param-value>
|
||||
</context-param>
|
||||
|
||||
<listener>
|
||||
<listener-class>
|
||||
org.dspace.app.util.DSpaceContextListener
|
||||
</listener-class>
|
||||
</listener>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>oai</servlet-name>
|
||||
<servlet-class>org.dspace.xoai.DSpaceOAIDataProvider</servlet-class>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>default</servlet-name>
|
||||
<url-pattern>/static/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>oai</servlet-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!--
|
||||
- The is the servlet deployment descriptor for Tomcat 4.0, for the OAI
|
||||
- Web application.
|
||||
- OAICat Configuration file - see OAICat documentation for details
|
||||
-
|
||||
- '${dspace.dir}' will be replaced with the directory where DSpace is installed
|
||||
-->
|
||||
|
||||
<web-app>
|
||||
<display-name>DSpace OAI-PMH 2.0</display-name>
|
||||
|
||||
<!-- DSpace configuration information -->
|
||||
<context-param>
|
||||
<param-name>dspace-config</param-name>
|
||||
<param-value>${dspace.dir}/config/dspace.cfg</param-value>
|
||||
<description>
|
||||
The location of the main DSpace configuration file
|
||||
</description>
|
||||
</context-param>
|
||||
|
||||
<context-param>
|
||||
<param-name>properties</param-name>
|
||||
<param-value>${dspace.dir}/config/oaicat.properties</param-value>
|
||||
<description>
|
||||
The location of the oaicat.properties file containing
|
||||
datapairs used to initialize the OAI repository software.
|
||||
</description>
|
||||
</context-param>
|
||||
|
||||
<!-- new ConfigurationService initialization for dspace.dir -->
|
||||
<context-param>
|
||||
<description>
|
||||
The location of the main DSpace configuration file
|
||||
</description>
|
||||
<param-name>dspace.dir</param-name>
|
||||
<param-value>${dspace.dir}</param-value>
|
||||
</context-param>
|
||||
|
||||
<!--
|
||||
Listener to initialise DSpace configuration and clean up the application
|
||||
-->
|
||||
<listener>
|
||||
<listener-class>
|
||||
org.dspace.app.util.DSpaceContextListener
|
||||
</listener-class>
|
||||
</listener>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>oai-handler</servlet-name>
|
||||
<servlet-class>ORG.oclc.oai.server.OAIHandler</servlet-class>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>default</servlet-name>
|
||||
<url-pattern>*.xsl</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>oai-handler</servlet-name>
|
||||
<url-pattern>/request</url-pattern>
|
||||
</servlet-mapping>
|
||||
</web-app>
|
||||
|
||||
@@ -1,770 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
|
||||
XSL Transform to convert OAI 2.0 responses into XHTML
|
||||
|
||||
By Christopher Gutteridge, University of Southampton
|
||||
|
||||
v1.1
|
||||
|
||||
modified version for DSpace by Ivan Masár <helix84@centrum.sk>, 2012.
|
||||
* response pages display number of results on top
|
||||
* badArgument error page displays forms to help build correct queries
|
||||
* Identify response page renders OAICat-specific "toolkit" description element
|
||||
|
||||
-->
|
||||
|
||||
<!--
|
||||
|
||||
Copyright (c) 2006 University of Southampton, UK. SO17 1BJ.
|
||||
|
||||
EPrints 3 is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
EPrints 3 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with EPrints 3; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
-->
|
||||
|
||||
|
||||
<!--
|
||||
|
||||
All the elements really needed for EPrints are done but if
|
||||
you want to use this XSL for other OAI archive you may want
|
||||
to make some minor changes or additions.
|
||||
|
||||
Not Done
|
||||
The 'about' section of 'record'
|
||||
The 'compression' part of 'identify'
|
||||
The optional attributes of 'resumptionToken'
|
||||
The optional 'setDescription' container of 'set'
|
||||
Encoding of special characters in forms <http://www.openarchives.org/OAI/openarchivesprotocol.html#SpecialCharacters>
|
||||
|
||||
All the links just link to oai_dc versions of records.
|
||||
|
||||
-->
|
||||
<xsl:stylesheet
|
||||
version="1.0"
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:oai="http://www.openarchives.org/OAI/2.0/"
|
||||
xmlns:tk="http://oai.dlib.vt.edu/OAI/metadata/toolkit"
|
||||
>
|
||||
|
||||
<xsl:output method="html"/>
|
||||
|
||||
|
||||
|
||||
<xsl:template name="style">
|
||||
td.value {
|
||||
vertical-align: top;
|
||||
padding-left: 1em;
|
||||
padding: 3px;
|
||||
}
|
||||
td.key {
|
||||
background-color: #e0e0ff;
|
||||
padding: 3px;
|
||||
text-align: right;
|
||||
border: 1px solid #c0c0c0;
|
||||
white-space: nowrap;
|
||||
font-weight: bold;
|
||||
vertical-align: top;
|
||||
}
|
||||
.result-count {
|
||||
margin-top:10px;
|
||||
background-color: #e0e0ff;
|
||||
padding: 3px;
|
||||
border: 1px solid #c0c0c0;
|
||||
white-space: nowrap;
|
||||
font-weight: bold;
|
||||
vertical-align: top;
|
||||
}
|
||||
.dcdata td.key {
|
||||
background-color: #ffffe0;
|
||||
}
|
||||
body {
|
||||
margin: 1em 2em 1em 2em;
|
||||
}
|
||||
h1, h2, h3 {
|
||||
font-family: sans-serif;
|
||||
clear: left;
|
||||
}
|
||||
h1 {
|
||||
padding-bottom: 4px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
h2 {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
h3 {
|
||||
margin-bottom: 0.3em;
|
||||
font-size: medium;
|
||||
}
|
||||
.link {
|
||||
border: 1px outset #88f;
|
||||
background-color: #c0c0ff;
|
||||
padding: 1px 4px 1px 4px;
|
||||
font-size: 80%;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
font-family: sans-serif;
|
||||
color: black;
|
||||
}
|
||||
.link:hover {
|
||||
color: red;
|
||||
}
|
||||
.link:active {
|
||||
color: red;
|
||||
border: 1px inset #88f;
|
||||
background-color: #a0a0df;
|
||||
}
|
||||
.oaiRecord, .oaiRecordTitle {
|
||||
background-color: #f0f0ff;
|
||||
border-style: solid;
|
||||
border-color: #d0d0d0;
|
||||
}
|
||||
h2.oaiRecordTitle {
|
||||
background-color: #e0e0ff;
|
||||
font-size: medium;
|
||||
font-weight: bold;
|
||||
padding: 10px;
|
||||
border-width: 2px 2px 0px 2px;
|
||||
margin: 0px;
|
||||
}
|
||||
.oaiRecord {
|
||||
margin-bottom: 3em;
|
||||
border-width: 2px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.results {
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
ul.quicklinks {
|
||||
margin-top: 2px;
|
||||
padding: 4px;
|
||||
text-align: left;
|
||||
border-bottom: 2px solid #ccc;
|
||||
border-top: 2px solid #ccc;
|
||||
clear: left;
|
||||
}
|
||||
ul.quicklinks li {
|
||||
font-size: 80%;
|
||||
display: inline;
|
||||
list-stlye: none;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
p.intro {
|
||||
font-size: 80%;
|
||||
}
|
||||
/* Order in HTML must be: verb, arguments. The displayed order is reversed here to conventional: arguments, verb. */
|
||||
#form1, #form2, #form3 {
|
||||
position: relative;
|
||||
}
|
||||
#form1div {
|
||||
position: relative;
|
||||
top: 7.5em;
|
||||
}
|
||||
#form2div {
|
||||
position: relative;
|
||||
top: 1.5em;
|
||||
}
|
||||
#form3div {
|
||||
position: relative;
|
||||
top: 3.5em;
|
||||
}
|
||||
#form1table, #form2table, #form3table {
|
||||
position: relative;
|
||||
top: -2em;
|
||||
}
|
||||
.value-error {
|
||||
background: #FF9999;
|
||||
text-align: left;
|
||||
}
|
||||
<xsl:call-template name='xmlstyle' />
|
||||
</xsl:template>
|
||||
|
||||
<xsl:variable name='identifier' select="substring-before(concat(substring-after(/oai:OAI-PMH/oai:request,'identifier='),'&'),'&')" />
|
||||
|
||||
<xsl:template match="/">
|
||||
<html>
|
||||
<head>
|
||||
<title>OAI 2.0 Request Results</title>
|
||||
<style><xsl:call-template name="style"/></style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>OAI 2.0 Request Results</h1>
|
||||
<xsl:call-template name="quicklinks"/>
|
||||
<p class="intro">You are viewing an HTML version of the XML OAI response. To see the underlying XML use your web browsers view source option. More information about this XSLT is at the <a href="#moreinfo">bottom of the page</a>.</p>
|
||||
<xsl:apply-templates select="/oai:OAI-PMH" />
|
||||
<xsl:call-template name="quicklinks"/>
|
||||
<h2><a name="moreinfo">About the XSLT</a></h2>
|
||||
<p>An XSLT file has converted the <a href="http://www.openarchives.org">OAI-PMH 2.0</a> responses into XHTML which looks nice in a browser which supports XSLT such as Mozilla, Firebird and Internet Explorer. The XSLT file was created by <a href="http://www.ecs.soton.ac.uk/people/cjg">Christopher Gutteridge</a> at the University of Southampton as part of the <a href="http://www.eprints.org/software/">GNU EPrints system</a>, and is freely redistributable under the <a href="http://www.gnu.org">GPL</a>.</p><p>If you want to use the XSL file on your own OAI interface you may but due to the way XSLT works you must install the XSL file on the same server as the OAI script, you can't just link to this copy.</p><p>For more information or to download the XSL file please see the <a href="http://software.eprints.org/xslt.php">OAI to XHTML XSLT homepage</a>.</p>
|
||||
|
||||
<script type="text/javascript"><![CDATA[
|
||||
<!--
|
||||
// don't submit blank form fields
|
||||
document.getElementById('form1').onsubmit = function(){
|
||||
var el = this.getElementsByTagName('input');
|
||||
for (var i=0; i<el.length; i++) {
|
||||
if (el[i].type == 'text' && el[i].value == '') {
|
||||
el[i].disabled = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
-->
|
||||
]]></script>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="quicklinks">
|
||||
<ul class="quicklinks">
|
||||
<li><a href="?verb=Identify">Identify</a> | </li>
|
||||
<li><a href="?verb=ListRecords&metadataPrefix=oai_dc">ListRecords</a> | </li>
|
||||
<li><a href="?verb=ListSets">ListSets</a> | </li>
|
||||
<li><a href="?verb=ListMetadataFormats">ListMetadataFormats</a> | </li>
|
||||
<li><a href="?verb=ListIdentifiers&metadataPrefix=oai_dc">ListIdentifiers</a></li>
|
||||
</ul>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="/oai:OAI-PMH">
|
||||
<table class="values">
|
||||
<tr><td class="key">Datestamp of response</td>
|
||||
<td class="value"><xsl:value-of select="oai:responseDate"/></td></tr>
|
||||
<tr><td class="key">Request base URL</td>
|
||||
<td class="value"><xsl:value-of select="oai:request"/></td></tr>
|
||||
<tr><td class="key">Request verb</td>
|
||||
<td class="value"><xsl:value-of select="oai:request/@verb"/></td></tr>
|
||||
</table>
|
||||
<xsl:choose>
|
||||
<xsl:when test="oai:error">
|
||||
<h2>OAI Error(s)</h2>
|
||||
<p>The request could not be completed due to the following error or errors.</p>
|
||||
<div class="results">
|
||||
<xsl:apply-templates select="oai:error"/>
|
||||
</div>
|
||||
<xsl:if test="oai:error/@code = 'badArgument'">
|
||||
<p>For your convenience, here's a form with possible combinations of arguments (required arguments are in bold text):</p>
|
||||
<form id="form1" method="GET">
|
||||
<div id='form1div'>
|
||||
<input type="submit" name="verb" value="ListRecords" />
|
||||
<input type="submit" name="verb" value="ListIdentifiers" />
|
||||
</div>
|
||||
<table id="form1table">
|
||||
<tr><td><b>metadataPrefix:</b></td><td><input type="text" name="metadataPrefix" value="" /></td></tr>
|
||||
<tr><td>set:</td><td><input type="text" name="set" /></td></tr>
|
||||
<tr><td>from:</td><td><input type="text" name="from" /></td><td>(YYYY-MM-DD)</td></tr>
|
||||
<tr><td>until:</td><td><input type="text" name="until" /></td><td>(YYYY-MM-DD)</td></tr>
|
||||
</table>
|
||||
</form>
|
||||
<p>Alternatively, you can provide only the resumptionToken:</p>
|
||||
<form name='form2' method="GET">
|
||||
<div id='form2div'>
|
||||
<input type="submit" name="verb" value="ListRecords" />
|
||||
<input type="submit" name="verb" value="ListIdentifiers" />
|
||||
</div>
|
||||
<table id="form2table">
|
||||
<tr><td><b>resumptionToken:</b></td><td><input type="text" name="resumptionToken" /></td></tr>
|
||||
</table>
|
||||
</form>
|
||||
<p>Or you can get a single record:</p>
|
||||
<form name='form3' method="GET">
|
||||
<div id='form3div'>
|
||||
<input type="submit" name="verb" value="GetRecord" />
|
||||
</div>
|
||||
<table id="form3table">
|
||||
<tr><td><b>metadataPrefix:</b></td><td><input type="text" name="metadataPrefix" value="" /></td></tr>
|
||||
<tr><td><b>identifier:</b></td><td><input type="text" name="identifier" /></td></tr>
|
||||
</table>
|
||||
</form>
|
||||
</xsl:if>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<p></p>
|
||||
<div class="results">
|
||||
<xsl:apply-templates select="oai:Identify" />
|
||||
<xsl:apply-templates select="oai:GetRecord"/>
|
||||
<xsl:apply-templates select="oai:ListRecords"/>
|
||||
<xsl:apply-templates select="oai:ListSets"/>
|
||||
<xsl:apply-templates select="oai:ListMetadataFormats"/>
|
||||
<xsl:apply-templates select="oai:ListIdentifiers"/>
|
||||
</div>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<!-- ERROR -->
|
||||
|
||||
<xsl:template match="/oai:OAI-PMH/oai:error">
|
||||
<table class="values">
|
||||
<tr><td class="key">Error Code</td>
|
||||
<td class="value"><xsl:value-of select="@code"/></td></tr>
|
||||
</table>
|
||||
<p class="error"><xsl:value-of select="." /></p>
|
||||
</xsl:template>
|
||||
|
||||
<!-- IDENTIFY -->
|
||||
|
||||
<xsl:template match="/oai:OAI-PMH/oai:Identify">
|
||||
<table class="values">
|
||||
<tr><td class="key">Repository Name</td>
|
||||
<td class="value"><xsl:value-of select="oai:repositoryName"/></td></tr>
|
||||
<tr><td class="key">Base URL</td>
|
||||
<td class="value"><xsl:value-of select="oai:baseURL"/></td></tr>
|
||||
<tr><td class="key">Protocol Version</td>
|
||||
<td class="value"><xsl:value-of select="oai:protocolVersion"/></td></tr>
|
||||
<tr><td class="key">Earliest Datestamp</td>
|
||||
<td class="value"><xsl:value-of select="oai:earliestDatestamp"/></td></tr>
|
||||
<tr><td class="key">Deleted Record Policy</td>
|
||||
<td class="value"><xsl:value-of select="oai:deletedRecord"/></td></tr>
|
||||
<tr><td class="key">Granularity</td>
|
||||
<td class="value"><xsl:value-of select="oai:granularity"/></td></tr>
|
||||
<xsl:apply-templates select="oai:adminEmail"/>
|
||||
</table>
|
||||
<xsl:apply-templates select="oai:description"/>
|
||||
<!--no warning about unsupported descriptions -->
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="/oai:OAI-PMH/oai:Identify/oai:adminEmail">
|
||||
<tr><td class="key">Admin Email</td>
|
||||
<td class="value"><xsl:value-of select="."/></td></tr>
|
||||
</xsl:template>
|
||||
|
||||
<!--
|
||||
Identify / Unsupported Description
|
||||
-->
|
||||
|
||||
<xsl:template match="oai:description/*" priority="-100">
|
||||
<xsl:choose>
|
||||
<xsl:when test="local-name(.) = 'toolkit'">
|
||||
<h2>Description: Toolkit</h2>
|
||||
<table class="values">
|
||||
<tr><td class="key">Title</td>
|
||||
<td class="value"><xsl:value-of select="tk:title"/></td></tr>
|
||||
<tr><td class="key">Author</td>
|
||||
<td class="value"><xsl:value-of select="concat(tk:author/tk:name, ' <', tk:author/tk:email, '>, ', tk:author/tk:institution)"/></td></tr>
|
||||
<tr><td class="key">Version</td>
|
||||
<td class="value"><xsl:value-of select="tk:version"/></td></tr>
|
||||
<tr><td class="key">URL</td>
|
||||
<td class="value"><xsl:value-of select="tk:URL"/></td></tr>
|
||||
<tr><td class="key">Icon</td>
|
||||
<td class="value"><img><xsl:attribute name="src"><xsl:value-of select="tk:toolkitIcon"/></xsl:attribute></img></td></tr>
|
||||
</table>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<h2>Unsupported Description Type</h2>
|
||||
<p>The XSL currently does not support this type of description.</p>
|
||||
<div class="xmlSource">
|
||||
<xsl:apply-templates select="." mode='xmlMarkup' />
|
||||
</div>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<!--
|
||||
Identify / OAI-Identifier
|
||||
-->
|
||||
|
||||
<xsl:template match="id:oai-identifier" xmlns:id="http://www.openarchives.org/OAI/2.0/oai-identifier">
|
||||
<h2>OAI-Identifier</h2>
|
||||
<table class="values">
|
||||
<tr><td class="key">Scheme</td>
|
||||
<td class="value"><xsl:value-of select="id:scheme"/></td></tr>
|
||||
<tr><td class="key">Repository Identifier</td>
|
||||
<td class="value"><xsl:value-of select="id:repositoryIdentifier"/></td></tr>
|
||||
<tr><td class="key">Delimiter</td>
|
||||
<td class="value"><xsl:value-of select="id:delimiter"/></td></tr>
|
||||
<tr><td class="key">Sample OAI Identifier</td>
|
||||
<td class="value"><xsl:value-of select="id:sampleIdentifier"/></td></tr>
|
||||
</table>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<!--
|
||||
Identify / EPrints
|
||||
-->
|
||||
|
||||
<xsl:template match="ep:eprints" xmlns:ep="http://www.openarchives.org/OAI/1.1/eprints">
|
||||
<h2>EPrints Description</h2>
|
||||
<xsl:if test="ep:content">
|
||||
<h3>Content</h3>
|
||||
<xsl:apply-templates select="ep:content"/>
|
||||
</xsl:if>
|
||||
<xsl:if test="ep:submissionPolicy">
|
||||
<h3>Submission Policy</h3>
|
||||
<xsl:apply-templates select="ep:submissionPolicy"/>
|
||||
</xsl:if>
|
||||
<h3>Metadata Policy</h3>
|
||||
<xsl:apply-templates select="ep:metadataPolicy"/>
|
||||
<h3>Data Policy</h3>
|
||||
<xsl:apply-templates select="ep:dataPolicy"/>
|
||||
<xsl:apply-templates select="ep:comment"/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="ep:content|ep:dataPolicy|ep:metadataPolicy|ep:submissionPolicy" xmlns:ep="http://www.openarchives.org/OAI/1.1/eprints">
|
||||
<xsl:if test="ep:text">
|
||||
<p><xsl:value-of select="ep:text" /></p>
|
||||
</xsl:if>
|
||||
<xsl:if test="ep:URL">
|
||||
<div><a href="{ep:URL}"><xsl:value-of select="ep:URL" /></a></div>
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="ep:comment" xmlns:ep="http://www.openarchives.org/OAI/1.1/eprints">
|
||||
<h3>Comment</h3>
|
||||
<div><xsl:value-of select="."/></div>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<!--
|
||||
Identify / Friends
|
||||
-->
|
||||
|
||||
<xsl:template match="fr:friends" xmlns:fr="http://www.openarchives.org/OAI/2.0/friends/">
|
||||
<h2>Friends</h2>
|
||||
<ul>
|
||||
<xsl:apply-templates select="fr:baseURL"/>
|
||||
</ul>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="fr:baseURL" xmlns:fr="http://www.openarchives.org/OAI/2.0/friends/">
|
||||
<li><xsl:value-of select="."/>
|
||||
<xsl:text> </xsl:text>
|
||||
<a class="link" href="{.}?verb=Identify">Identify</a></li>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<!--
|
||||
Identify / Branding
|
||||
-->
|
||||
|
||||
<xsl:template match="br:branding" xmlns:br="http://www.openarchives.org/OAI/2.0/branding/">
|
||||
<h2>Branding</h2>
|
||||
<xsl:apply-templates select="br:collectionIcon"/>
|
||||
<xsl:apply-templates select="br:metadataRendering"/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="br:collectionIcon" xmlns:br="http://www.openarchives.org/OAI/2.0/branding/">
|
||||
<h3>Icon</h3>
|
||||
<xsl:choose>
|
||||
<xsl:when test="link!=''">
|
||||
<a href="{br:link}"><img src="{br:url}" alt="{br:title}" width="{br:width}" height="{br:height}" border="0" /></a>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<img src="{br:url}" alt="{br:title}" width="{br:width}" height="{br:height}" border="0" />
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="br:metadataRendering" xmlns:br="http://www.openarchives.org/OAI/2.0/branding/">
|
||||
<h3>Metadata Rendering Rule</h3>
|
||||
<table class="values">
|
||||
<tr><td class="key">URL</td>
|
||||
<td class="value"><xsl:value-of select="."/></td></tr>
|
||||
<tr><td class="key">Namespace</td>
|
||||
<td class="value"><xsl:value-of select="@metadataNamespace"/></td></tr>
|
||||
<tr><td class="key">Mime Type</td>
|
||||
<td class="value"><xsl:value-of select="@mimetype"/></td></tr>
|
||||
</table>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
|
||||
<!--
|
||||
Identify / Gateway
|
||||
-->
|
||||
|
||||
<xsl:template match="gw:gateway" xmlns:gw="http://www.openarchives.org/OAI/2.0/gateway/x">
|
||||
<h2>Gateway Information</h2>
|
||||
<table class="values">
|
||||
<tr><td class="key">Source</td>
|
||||
<td class="value"><xsl:value-of select="gw:source"/></td></tr>
|
||||
<tr><td class="key">Description</td>
|
||||
<td class="value"><xsl:value-of select="gw:gatewayDescription"/></td></tr>
|
||||
<xsl:apply-templates select="gw:gatewayAdmin"/>
|
||||
<xsl:if test="gw:gatewayURL">
|
||||
<tr><td class="key">URL</td>
|
||||
<td class="value"><xsl:value-of select="gw:gatewayURL"/></td></tr>
|
||||
</xsl:if>
|
||||
<xsl:if test="gw:gatewayNotes">
|
||||
<tr><td class="key">Notes</td>
|
||||
<td class="value"><xsl:value-of select="gw:gatewayNotes"/></td></tr>
|
||||
</xsl:if>
|
||||
</table>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="gw:gatewayAdmin" xmlns:gw="http://www.openarchives.org/OAI/2.0/gateway/">
|
||||
<tr><td class="key">Admin</td>
|
||||
<td class="value"><xsl:value-of select="."/></td></tr>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<!-- GetRecord -->
|
||||
|
||||
<xsl:template match="oai:GetRecord">
|
||||
<xsl:apply-templates select="oai:record" />
|
||||
</xsl:template>
|
||||
|
||||
<!-- ListRecords -->
|
||||
|
||||
<xsl:template match="oai:ListRecords">
|
||||
<div class="result-count">Results fetched: <xsl:value-of select="count(oai:record)"/></div>
|
||||
<xsl:apply-templates select="oai:record" />
|
||||
<xsl:apply-templates select="oai:resumptionToken" />
|
||||
</xsl:template>
|
||||
|
||||
<!-- ListIdentifiers -->
|
||||
|
||||
<xsl:template match="oai:ListIdentifiers">
|
||||
<div class="result-count">Results fetched: <xsl:value-of select="count(oai:header)"/></div>
|
||||
<xsl:apply-templates select="oai:header" />
|
||||
<xsl:apply-templates select="oai:resumptionToken" />
|
||||
</xsl:template>
|
||||
|
||||
<!-- ListSets -->
|
||||
|
||||
<xsl:template match="oai:ListSets">
|
||||
<div class="result-count">Results fetched: <xsl:value-of select="count(oai:set)"/></div>
|
||||
<xsl:apply-templates select="oai:set" />
|
||||
<xsl:apply-templates select="oai:resumptionToken" />
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="oai:set">
|
||||
<h2>Set</h2>
|
||||
<table class="values">
|
||||
<tr><td class="key">setName</td>
|
||||
<td class="value"><xsl:value-of select="oai:setName"/></td></tr>
|
||||
<xsl:apply-templates select="oai:setSpec" />
|
||||
</table>
|
||||
</xsl:template>
|
||||
|
||||
<!-- ListMetadataFormats -->
|
||||
|
||||
<xsl:template match="oai:ListMetadataFormats">
|
||||
<xsl:choose>
|
||||
<xsl:when test="$identifier">
|
||||
<p>This is a list of metadata formats available for the record "<xsl:value-of select='$identifier' />". Use these links to view the metadata: <xsl:apply-templates select="oai:metadataFormat/oai:metadataPrefix" /></p>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<p>This is a list of metadata formats available from this archive.</p>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:apply-templates select="oai:metadataFormat" />
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="oai:metadataFormat">
|
||||
<h2>Metadata Format</h2>
|
||||
<table class="values">
|
||||
<tr><td class="key">metadataPrefix</td>
|
||||
<td class="value"><a class="link" href="?verb=ListRecords&metadataPrefix={oai:metadataPrefix}"><xsl:value-of select="oai:metadataPrefix"/></a></td></tr>
|
||||
<tr><td class="key">metadataNamespace</td>
|
||||
<td class="value"><xsl:value-of select="oai:metadataNamespace"/></td></tr>
|
||||
<tr><td class="key">schema</td>
|
||||
<td class="value"><a href="{oai:schema}"><xsl:value-of select="oai:schema"/></a></td></tr>
|
||||
</table>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="oai:metadataPrefix">
|
||||
<xsl:text> </xsl:text><a class="link" href="?verb=GetRecord&metadataPrefix={.}&identifier={$identifier}"><xsl:value-of select='.' /></a>
|
||||
</xsl:template>
|
||||
|
||||
<!-- record object -->
|
||||
|
||||
<xsl:template match="oai:record">
|
||||
<h2 class="oaiRecordTitle">OAI Record: <xsl:value-of select="oai:header/oai:identifier"/></h2>
|
||||
<div class="oaiRecord">
|
||||
<xsl:apply-templates select="oai:header" />
|
||||
<xsl:apply-templates select="oai:metadata" />
|
||||
<xsl:apply-templates select="oai:about" />
|
||||
</div>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="oai:header">
|
||||
<h3>OAI Record Header</h3>
|
||||
<table class="values">
|
||||
<tr><td class="key">OAI Identifier</td>
|
||||
<td class="value">
|
||||
<xsl:value-of select="oai:identifier"/>
|
||||
<xsl:text> </xsl:text><a class="link" href="?verb=GetRecord&metadataPrefix=oai_dc&identifier={oai:identifier}">oai_dc</a>
|
||||
<xsl:text> </xsl:text><a class="link" href="?verb=ListMetadataFormats&identifier={oai:identifier}">formats</a>
|
||||
</td></tr>
|
||||
<tr><td class="key">Datestamp</td>
|
||||
<td class="value"><xsl:value-of select="oai:datestamp"/></td></tr>
|
||||
<xsl:apply-templates select="oai:setSpec" />
|
||||
</table>
|
||||
<xsl:if test="@status='deleted'">
|
||||
<p>This record has been deleted.</p>
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="oai:about">
|
||||
<p>"about" part of record container not supported by the XSL</p>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="oai:metadata">
|
||||
 
|
||||
<div class="metadata">
|
||||
<xsl:apply-templates select="*" />
|
||||
</div>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- oai setSpec object -->
|
||||
|
||||
<xsl:template match="oai:setSpec">
|
||||
<tr><td class="key">setSpec</td>
|
||||
<td class="value"><xsl:value-of select="."/>
|
||||
<xsl:text> </xsl:text><a class="link" href="?verb=ListIdentifiers&metadataPrefix=oai_dc&set={.}">Identifiers</a>
|
||||
<xsl:text> </xsl:text><a class="link" href="?verb=ListRecords&metadataPrefix=oai_dc&set={.}">Records</a>
|
||||
</td></tr>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
|
||||
<!-- oai resumptionToken -->
|
||||
|
||||
<xsl:template match="oai:resumptionToken">
|
||||
<p>There are more results.</p>
|
||||
<table class="values">
|
||||
<tr><td class="key">resumptionToken:</td>
|
||||
<td class="value"><xsl:value-of select="."/>
|
||||
<xsl:text> </xsl:text>
|
||||
<a class="link" href="?verb={/oai:OAI-PMH/oai:request/@verb}&resumptionToken={.}">Resume</a></td></tr>
|
||||
</table>
|
||||
</xsl:template>
|
||||
|
||||
<!-- unknown metadata format -->
|
||||
|
||||
<xsl:template match="oai:metadata/*" priority='-100'>
|
||||
<h3>Unknown Metadata Format</h3>
|
||||
<div class="xmlSource">
|
||||
<xsl:apply-templates select="." mode='xmlMarkup' />
|
||||
</div>
|
||||
</xsl:template>
|
||||
|
||||
<!-- oai_dc record -->
|
||||
|
||||
<xsl:template match="oai_dc:dc" xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" >
|
||||
<div class="dcdata">
|
||||
<h3>Dublin Core Metadata (oai_dc)</h3>
|
||||
<table class="dcdata">
|
||||
<xsl:apply-templates select="*" />
|
||||
</table>
|
||||
</div>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="dc:title" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<tr><td class="key">Title</td><td class="value"><xsl:value-of select="."/></td></tr></xsl:template>
|
||||
|
||||
<xsl:template match="dc:creator" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<tr><td class="key">Author or Creator</td><td class="value"><xsl:value-of select="."/></td></tr></xsl:template>
|
||||
|
||||
<xsl:template match="dc:subject" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<tr><td class="key">Subject and Keywords</td><td class="value"><xsl:value-of select="."/></td></tr></xsl:template>
|
||||
|
||||
<xsl:template match="dc:description" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<tr><td class="key">Description</td><td class="value"><xsl:value-of select="."/></td></tr></xsl:template>
|
||||
|
||||
<xsl:template match="dc:publisher" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<tr><td class="key">Publisher</td><td class="value"><xsl:value-of select="."/></td></tr></xsl:template>
|
||||
|
||||
<xsl:template match="dc:contributor" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<tr><td class="key">Other Contributor</td><td class="value"><xsl:value-of select="."/></td></tr></xsl:template>
|
||||
|
||||
<xsl:template match="dc:date" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<tr><td class="key">Date</td><td class="value"><xsl:value-of select="."/></td></tr></xsl:template>
|
||||
|
||||
<xsl:template match="dc:type" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<tr><td class="key">Resource Type</td><td class="value"><xsl:value-of select="."/></td></tr></xsl:template>
|
||||
|
||||
<xsl:template match="dc:format" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<tr><td class="key">Format</td><td class="value"><xsl:value-of select="."/></td></tr></xsl:template>
|
||||
|
||||
<xsl:template match="dc:identifier" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<tr><td class="key">Resource Identifier</td><td class="value"><xsl:value-of select="."/></td></tr></xsl:template>
|
||||
|
||||
<xsl:template match="dc:source" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<tr><td class="key">Source</td><td class="value"><xsl:value-of select="."/></td></tr></xsl:template>
|
||||
|
||||
<xsl:template match="dc:language" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<tr><td class="key">Language</td><td class="value"><xsl:value-of select="."/></td></tr></xsl:template>
|
||||
|
||||
<xsl:template match="dc:relation" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<tr><td class="key">Relation</td><td class="value">
|
||||
<xsl:choose>
|
||||
<xsl:when test='starts-with(.,"http" )'>
|
||||
<xsl:choose>
|
||||
<xsl:when test='string-length(.) > 50'>
|
||||
<a class="link" href="{.}">URL</a>
|
||||
<i> URL not shown as it is very long.</i>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<a href="{.}"><xsl:value-of select="."/></a>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="."/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</td></tr></xsl:template>
|
||||
|
||||
<xsl:template match="dc:coverage" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<tr><td class="key">Coverage</td><td class="value"><xsl:value-of select="."/></td></tr></xsl:template>
|
||||
|
||||
<xsl:template match="dc:rights" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<tr><td class="key">Rights Management</td><td class="value"><xsl:value-of select="."/></td></tr></xsl:template>
|
||||
|
||||
<!-- XML Pretty Maker -->
|
||||
|
||||
<xsl:template match="node()" mode='xmlMarkup'>
|
||||
<div class="xmlBlock">
|
||||
<<span class="xmlTagName"><xsl:value-of select='name(.)' /></span><xsl:apply-templates select="@*" mode='xmlMarkup'/>><xsl:apply-templates select="node()" mode='xmlMarkup' /></<span class="xmlTagName"><xsl:value-of select='name(.)' /></span>>
|
||||
</div>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="text()" mode='xmlMarkup'><span class="xmlText"><xsl:value-of select='.' /></span></xsl:template>
|
||||
|
||||
<xsl:template match="@*" mode='xmlMarkup'>
|
||||
<xsl:text> </xsl:text><span class="xmlAttrName"><xsl:value-of select='name()' /></span>="<span class="xmlAttrValue"><xsl:value-of select='.' /></span>"
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="xmlstyle">
|
||||
.xmlSource {
|
||||
font-size: 70%;
|
||||
border: solid #c0c0a0 1px;
|
||||
background-color: #ffffe0;
|
||||
padding: 2em 2em 2em 0em;
|
||||
}
|
||||
.xmlBlock {
|
||||
padding-left: 2em;
|
||||
}
|
||||
.xmlTagName {
|
||||
color: #800000;
|
||||
font-weight: bold;
|
||||
}
|
||||
.xmlAttrName {
|
||||
font-weight: bold;
|
||||
}
|
||||
.xmlAttrValue {
|
||||
color: #0000c0;
|
||||
}
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
||||
|
||||
@@ -1,339 +0,0 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
BIN
dspace-oai/dspace-oai-webapp/src/main/webapp/static/lyncode.png
Normal file
BIN
dspace-oai/dspace-oai-webapp/src/main/webapp/static/lyncode.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.7 KiB |
1150
dspace-oai/dspace-oai-webapp/src/main/webapp/static/style.xsl
Normal file
1150
dspace-oai/dspace-oai-webapp/src/main/webapp/static/style.xsl
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,24 +1,35 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-oai</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<name>DSpace OAI</name>
|
||||
<description>Parent for DSpace OAI Service Provider Webapplication</description>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>dspace-parent</artifactId>
|
||||
<groupId>org.dspace</groupId>
|
||||
<version>3.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>dspace-oai</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<!--
|
||||
A Parent POM that Maven inherits DSpace Default
|
||||
POM atrributes from.
|
||||
-->
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-parent</artifactId>
|
||||
<version>3.0-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
<module>dspace-oai-api</module>
|
||||
<module>dspace-oai-webapp</module>
|
||||
</modules>
|
||||
</project>
|
||||
|
||||
<name>DSpace OAI 2.0</name>
|
||||
<description>Parent project for the OAI API and Webapp</description>
|
||||
<url>http://www.lyncode.com/dspace/addons/xoai</url>
|
||||
<modules>
|
||||
<module>dspace-oai-api</module>
|
||||
<module>dspace-oai-webapp</module>
|
||||
</modules>
|
||||
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<name>DSpace @ Lyncode</name>
|
||||
<email>dspace@lyncode.com</email>
|
||||
<organization>Lyncode</organization>
|
||||
<organizationUrl>http://www.lyncode.com</organizationUrl>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>helix84</id>
|
||||
<name>Ivan Másar</name>
|
||||
<email>helix84@centrum.sk</email>
|
||||
</developer>
|
||||
</developers>
|
||||
</project>
|
||||
|
||||
@@ -4,7 +4,4 @@
|
||||
<Parameter name="dspace-config" override="false"
|
||||
value="${dspace.dir}/config/dspace.cfg"
|
||||
description="Path to the DSpace configuration file." />
|
||||
<Parameter name="properties" override="false"
|
||||
value="${dspace.dir}/config/oaicat.properties"
|
||||
description="The location of the oaicat.properties file." />
|
||||
</Context>
|
||||
</Context>
|
||||
|
||||
@@ -356,12 +356,12 @@
|
||||
</command>
|
||||
|
||||
<command>
|
||||
<name>update-discovery-index</name>
|
||||
<description>Update Discovery Solr Search Index</description>
|
||||
<step>
|
||||
<class>org.dspace.discovery.IndexClient</class>
|
||||
</step>
|
||||
</command>
|
||||
<name>update-discovery-index</name>
|
||||
<description>Update Discovery Solr Search Index</description>
|
||||
<step>
|
||||
<class>org.dspace.discovery.IndexClient</class>
|
||||
</step>
|
||||
</command>
|
||||
|
||||
<command>
|
||||
<name>migrate-embargo</name>
|
||||
@@ -371,6 +371,12 @@
|
||||
</step>
|
||||
</command>
|
||||
|
||||
|
||||
<command>
|
||||
<name>oai</name>
|
||||
<description>OAI script manager</description>
|
||||
<step>
|
||||
<class>org.dspace.xoai.app.XOAI</class>
|
||||
</step>
|
||||
</command>
|
||||
|
||||
</commands>
|
||||
|
||||
@@ -1,108 +1,25 @@
|
||||
#---------------------------------------------------------------#
|
||||
#-------------OAI-PMH & OAI-ORE CONFIGURATIONS------------------#
|
||||
#--------------------XOAI CONFIGURATIONS------------------------#
|
||||
#---------------------------------------------------------------#
|
||||
# These configs are used by both OAI-PMH and OAI-ORE #
|
||||
# (Harvester) Interfaces. #
|
||||
#---------------------------------------------------------------#
|
||||
# The base URL of the OAI webapp (do not include /request).
|
||||
dspace.oai.url = ${dspace.baseUrl}/oai
|
||||
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
#--------------OAI-PMH SPECIFIC CONFIGURATIONS------------------#
|
||||
#---------------------------------------------------------------#
|
||||
# These configs are only used by the OAI-PMH interface #
|
||||
# These configs are used by the XOAI #
|
||||
#---------------------------------------------------------------#
|
||||
|
||||
# Max response size for DIDL. This is the maximum size in bytes of the files you
|
||||
# wish to enclose Base64 encoded in your responses, remember that the base64
|
||||
# encoding process uses a lot of memory. We recommend at most 200000 for answers
|
||||
# of 30 records each on a 1 Gigabyte machine. Ultimately, this will change to a
|
||||
# streaming model and remove this restriction. Also please remember to allocate
|
||||
# plenty of memory, at least 512 MB to your Tomcat.
|
||||
#
|
||||
# didl.maxresponse = 0
|
||||
# Storage: solr | database
|
||||
storage=solr
|
||||
|
||||
# DSpace by default uses 100 records as the limit for the oai responses.
|
||||
# This can be altered by enabling the oai.response.max-records parameter
|
||||
# and setting the desired amount of results.
|
||||
response.max-records = 100
|
||||
# Base solr index
|
||||
solr.url=${solr.server}/oai
|
||||
# OAI persistent identifier prefix.
|
||||
# Format - oai:PREFIX:HANDLE
|
||||
identifier.prefix = ${dspace.hostname}
|
||||
# Base url for bitstreams
|
||||
bitstream.baseUrl = ${dspace.url}
|
||||
|
||||
# Base Configuration Directory
|
||||
config.dir = ${dspace.dir}/config/modules/oai
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
#--------------OAI HARVESTING CONFIGURATIONS--------------------#
|
||||
#---------------------------------------------------------------#
|
||||
# These configs are only used by the OAI-ORE related functions #
|
||||
#---------------------------------------------------------------#
|
||||
# Cache enabled?
|
||||
cache.enabled = true
|
||||
|
||||
### Harvester settings
|
||||
|
||||
# Crosswalk settings; the {name} value must correspond to a declared ingestion crosswalk
|
||||
# harvester.oai.metadataformats.{name} = {namespace},{optional display name}
|
||||
# The display name is only used in the xmlui for the jspui there are entries in the
|
||||
# Messages.properties in the form jsp.tools.edit-collection.form.label21.select.{name}
|
||||
harvester.oai.metadataformats.dc = http://www.openarchives.org/OAI/2.0/oai_dc/, Simple Dublin Core
|
||||
harvester.oai.metadataformats.qdc = http://purl.org/dc/terms/, Qualified Dublin Core
|
||||
harvester.oai.metadataformats.dim = http://www.dspace.org/xmlns/dspace/dim, DSpace Intermediate Metadata
|
||||
|
||||
# This field works in much the same way as harvester.oai.metadataformats.PluginName
|
||||
# The {name} must correspond to a declared ingestion crosswalk, while the
|
||||
# {namespace} must be supported by the target OAI-PMH provider when harvesting content.
|
||||
# harvester.oai.oreSerializationFormat.{name} = {namespace}
|
||||
|
||||
# Determines whether the harvester scheduling process should be started
|
||||
# automatically when the DSpace webapp is deployed.
|
||||
# default: false
|
||||
harvester.autoStart=false
|
||||
|
||||
# Amount of time subtracted from the from argument of the PMH request to account
|
||||
# for the time taken to negotiate a connection. Measured in seconds. Default value is 120.
|
||||
#harvester.timePadding = 120
|
||||
|
||||
# How frequently the harvest scheduler checks the remote provider for updates,
|
||||
# measured in minutes. The default value is 12 hours (or 720 minutes)
|
||||
#harvester.harvestFrequency = 720
|
||||
|
||||
# The heartbeat is the frequency at which the harvest scheduler queries the local
|
||||
# database to determine if any collections are due for a harvest cycle (based on
|
||||
# the harvestFrequency) value. The scheduler is optimized to then sleep until the
|
||||
# next collection is actually ready to be harvested. The minHeartbeat and
|
||||
# maxHeartbeat are the lower and upper bounds on this timeframe. Measured in seconds.
|
||||
# Default minHeartbeat is 30. Default maxHeartbeat is 3600.
|
||||
#harvester.minHeartbeat = 30
|
||||
#harvester.maxHeartbeat = 3600
|
||||
|
||||
# How many harvest process threads the scheduler can spool up at once. Default value is 3.
|
||||
#harvester.maxThreads = 3
|
||||
|
||||
# How much time passess before a harvest thread is terminated. The termination process
|
||||
# waits for the current item to complete ingest and saves progress made up to that point.
|
||||
# Measured in hours. Default value is 24.
|
||||
#harvester.threadTimeout = 24
|
||||
|
||||
# When harvesting an item that contains an unknown schema or field within a schema what
|
||||
# should the harvester do? Either add a new registry item for the field or schema, ignore
|
||||
# the specific field or schema (importing everything else about the item), or fail with
|
||||
# an error. The default value if undefined is: fail.
|
||||
# Possible values: 'fail', 'add', or 'ignore'
|
||||
harvester.unknownField = add
|
||||
harvester.unknownSchema = fail
|
||||
|
||||
# The webapp responsible for minting the URIs for ORE Resource Maps.
|
||||
# If using oai, the dspace.oai.uri config value must be set.
|
||||
# The URIs generated for ORE ReMs follow the following convention for both cases.
|
||||
# format: [baseURI]/metadata/handle/[theHandle]/ore.xml
|
||||
# Default value is oai
|
||||
#ore.authoritative.source = oai
|
||||
|
||||
# A harvest process will attempt to scan the metadata of the incoming items
|
||||
# (dc.identifier.uri field, to be exact) to see if it looks like a handle.
|
||||
# If so, it matches the pattern against the values of this parameter.
|
||||
# If there is a match the new item is assigned the handle from the metadata value
|
||||
# instead of minting a new one. Default value: hdl.handle.net
|
||||
#harvester.acceptedHandleServer = hdl.handle.net, handle.myu.edu
|
||||
|
||||
# Pattern to reject as an invalid handle prefix (known test string, for example)
|
||||
# when attempting to find the handle of harvested items. If there is a match with
|
||||
# this config parameter, a new handle will be minted instead. Default value: 123456789.
|
||||
#harvester.rejectedHandlePrefix = 123456789, myTestHandle
|
||||
# Base Cache Directory
|
||||
cache.dir = ${dspace.dir}/var/oai
|
||||
|
||||
132
dspace/config/modules/oai/metadataFormats/didl.xsl
Normal file
132
dspace/config/modules/oai/metadataFormats/didl.xsl
Normal file
@@ -0,0 +1,132 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
|
||||
|
||||
The contents of this file are subject to the license and copyright
|
||||
detailed in the LICENSE and NOTICE files at the root of the source
|
||||
tree and available online at
|
||||
|
||||
http://www.dspace.org/license/
|
||||
Developed by DSpace @ Lyncode <dspace@lyncode.com>
|
||||
|
||||
> http://www.openarchives.org/OAI/2.0/oai_dc.xsd
|
||||
|
||||
-->
|
||||
<xsl:stylesheet
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:doc="http://www.lyncode.com/xoai"
|
||||
version="1.0">
|
||||
<xsl:output omit-xml-declaration="yes" method="xml" indent="yes" />
|
||||
|
||||
<xsl:template match="/">
|
||||
<d:DIDL xmlns:d="urn:mpeg:mpeg21:2002:02-DIDL-NS"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="urn:mpeg:mpeg21:2002:02-DIDL-NS http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-21_schema_files/did/didl.xsd">
|
||||
<xsl:if test="doc:metadata/doc:element[@name='dc']/doc:element[@name='date']/doc:element[@name='available']/doc:element/doc:field[@name='value']">
|
||||
<d:DIDLInfo>
|
||||
<dcterms:created xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://purl.org/dc/terms/ ">
|
||||
<xsl:value-of select="doc:metadata/doc:element[@name='dc']/doc:element[@name='date']/doc:element[@name='available']/doc:element/doc:field/text()" />
|
||||
</dcterms:created>
|
||||
</d:DIDLInfo>
|
||||
</xsl:if>
|
||||
<d:Item>
|
||||
<xsl:attribute name="id">
|
||||
<xsl:value-of select="doc:metadata/doc:element[@name='others']/doc:field[@name='handle']/text()" />
|
||||
</xsl:attribute>
|
||||
<d:Descriptor>
|
||||
<d:Statement mimeType="application/xml; charset=utf-8">
|
||||
<dii:Identifier xmlns:dii="urn:mpeg:mpeg21:2002:01-DII-NS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:mpeg:mpeg21:2002:01-DII-NS http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-21_schema_files/dii/dii.xsd">urn:hdl:<xsl:value-of select="doc:metadata/doc:element[@name='others']/doc:field[@name='handle']/text()" /></dii:Identifier>
|
||||
</d:Statement>
|
||||
</d:Descriptor>
|
||||
<d:Descriptor>
|
||||
<d:Statement mimeType="application/xml; charset=utf-8">
|
||||
<oai_dc:dc xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd">
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='title']/doc:element/doc:field[@name='value']">
|
||||
<dc:title><xsl:value-of select="." /></dc:title>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='contributor']/doc:element[@name='author']/doc:element/doc:field[@name='value']">
|
||||
<dc:creator><xsl:value-of select="." /></dc:creator>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='contributor']/doc:element[@name!='author']/doc:element/doc:field[@name='value']">
|
||||
<dc:contributor><xsl:value-of select="." /></dc:contributor>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='subject']/doc:element/doc:field[@name='value']">
|
||||
<dc:subject><xsl:value-of select="." /></dc:subject>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='description']/doc:element/doc:field[@name='value']">
|
||||
<dc:description><xsl:value-of select="." /></dc:description>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='description']/doc:element[@name='abstract']/doc:element/doc:field[@name='value']">
|
||||
<dc:description><xsl:value-of select="." /></dc:description>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='date']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:date><xsl:value-of select="." /></dc:date>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='type']/doc:element/doc:field[@name='value']">
|
||||
<dc:type><xsl:value-of select="." /></dc:type>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='identifier']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:identifier><xsl:value-of select="." /></dc:identifier>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='language']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:language><xsl:value-of select="." /></dc:language>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='relation']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:relation><xsl:value-of select="." /></dc:relation>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='relation']/doc:element/doc:field[@name='value']">
|
||||
<dc:relation><xsl:value-of select="." /></dc:relation>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='rights']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:rights><xsl:value-of select="." /></dc:rights>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='rights']/doc:element/doc:field[@name='value']">
|
||||
<dc:rights><xsl:value-of select="." /></dc:rights>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='bitstreams']/doc:element[@name='bitstream']/doc:field[@name='format']">
|
||||
<dc:format><xsl:value-of select="." /></dc:format>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='covarage']/doc:element/doc:field[@name='value']">
|
||||
<dc:covarage><xsl:value-of select="." /></dc:covarage>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='covarage']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:covarage><xsl:value-of select="." /></dc:covarage>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='publisher']/doc:element/doc:field[@name='value']">
|
||||
<dc:publisher><xsl:value-of select="." /></dc:publisher>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='publisher']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:publisher><xsl:value-of select="." /></dc:publisher>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='source']/doc:element/doc:field[@name='value']">
|
||||
<dc:source><xsl:value-of select="." /></dc:source>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='source']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:source><xsl:value-of select="." /></dc:source>
|
||||
</xsl:for-each>
|
||||
</oai_dc:dc>
|
||||
</d:Statement>
|
||||
</d:Descriptor>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='bundles']/doc:element[@name='bundle']">
|
||||
<xsl:if test="doc:field[@name='name']/text() = 'ORIGINAL'">
|
||||
<xsl:for-each select="doc:element[@name='bitstreams']/doc:element">
|
||||
<d:Component>
|
||||
<xsl:attribute name="id">
|
||||
<xsl:value-of select="/doc:metadata/doc:element[@name='others']/doc:field[@name='handle']/text()"></xsl:value-of>/<xsl:value-of select="doc:field[@name='sid']/text()"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
<d:Resource>
|
||||
<xsl:attribute name="ref">
|
||||
<xsl:value-of select="doc:field[@name='url']/text()"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="mimeType">
|
||||
<xsl:value-of select="doc:field[@name='format']/text()"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
</d:Resource>
|
||||
</d:Component>
|
||||
</xsl:for-each>
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
</d:Item>
|
||||
</d:DIDL>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
86
dspace/config/modules/oai/metadataFormats/dim.xsl
Normal file
86
dspace/config/modules/oai/metadataFormats/dim.xsl
Normal file
@@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
|
||||
The contents of this file are subject to the license and copyright detailed
|
||||
in the LICENSE and NOTICE files at the root of the source tree and available
|
||||
online at http://www.dspace.org/license/
|
||||
|
||||
Developed by DSpace @ Lyncode <dspace@lyncode.com>
|
||||
|
||||
-->
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:doc="http://www.lyncode.com/xoai" version="1.0">
|
||||
<xsl:output omit-xml-declaration="yes" method="xml" indent="yes" />
|
||||
|
||||
<!-- An identity transformation to show the internal XOAI generated XML -->
|
||||
<xsl:template match="/">
|
||||
<dim:dim xmlns:dim="http://www.dspace.org/xmlns/dspace/dim" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.dspace.org/xmlns/dspace/dim http://www.dspace.org/schema/dim.xsd">
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element/doc:element">
|
||||
<xsl:choose>
|
||||
<xsl:when test="doc:element">
|
||||
<dim:field>
|
||||
<xsl:attribute name="mdschema">
|
||||
<xsl:value-of select="../../@name" />
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="element">
|
||||
<xsl:value-of select="../@name" />
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="qualifier">
|
||||
<xsl:value-of select="@name" />
|
||||
</xsl:attribute>
|
||||
<xsl:choose>
|
||||
<xsl:when test="doc:element[@name='none']"></xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:attribute name="lang">
|
||||
<xsl:value-of select="doc:element/@name" />
|
||||
</xsl:attribute>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:if test="doc:element/doc:field[@name='authority']">
|
||||
<xsl:attribute name="authority">
|
||||
<xsl:value-of select="doc:element/doc:field[@name='authority']/text()" />
|
||||
</xsl:attribute>
|
||||
</xsl:if>
|
||||
<xsl:if test="doc:element/doc:field[@name='confidence']">
|
||||
<xsl:attribute name="confidence">
|
||||
<xsl:value-of select="doc:element/doc:field[@name='confidence']/text()" />
|
||||
</xsl:attribute>
|
||||
</xsl:if>
|
||||
<xsl:value-of select="doc:element/doc:field[@name='value']/text()"></xsl:value-of>
|
||||
</dim:field>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<dim:field>
|
||||
<xsl:attribute name="mdschema">
|
||||
<xsl:value-of select="../../@name" />
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="element">
|
||||
<xsl:value-of select="../@name" />
|
||||
</xsl:attribute>
|
||||
<xsl:choose>
|
||||
<xsl:when test="@name='none'"></xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:attribute name="lang">
|
||||
<xsl:value-of select="@name" />
|
||||
</xsl:attribute>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:if test="doc:field[@name='authority']">
|
||||
<xsl:attribute name="authority">
|
||||
<xsl:value-of select="doc:field[@name='authority']/text()" />
|
||||
</xsl:attribute>
|
||||
</xsl:if>
|
||||
<xsl:if test="doc:field[@name='confidence']">
|
||||
<xsl:attribute name="confidence">
|
||||
<xsl:value-of select="doc:field[@name='confidence']/text()" />
|
||||
</xsl:attribute>
|
||||
</xsl:if>
|
||||
<xsl:value-of select="doc:field[@name='value']/text()"></xsl:value-of>
|
||||
</dim:field>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:for-each>
|
||||
</dim:dim>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
116
dspace/config/modules/oai/metadataFormats/etdms.xsl
Normal file
116
dspace/config/modules/oai/metadataFormats/etdms.xsl
Normal file
@@ -0,0 +1,116 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
|
||||
|
||||
The contents of this file are subject to the license and copyright
|
||||
detailed in the LICENSE and NOTICE files at the root of the source
|
||||
tree and available online at
|
||||
|
||||
http://www.dspace.org/license/
|
||||
Developed by DSpace @ Lyncode <dspace@lyncode.com>
|
||||
|
||||
-->
|
||||
<xsl:stylesheet
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:doc="http://www.lyncode.com/xoai"
|
||||
version="1.0">
|
||||
<xsl:output omit-xml-declaration="yes" method="xml" indent="yes" />
|
||||
|
||||
<xsl:template match="/">
|
||||
<thesis xmlns="http://www.ndltd.org/standards/metadata/etdms/1.0/"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.ndltd.org/standards/metadata/etdms/1.0/ http://www.ndltd.org/standards/metadata/etdms/1.0/etdms.xsd">
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='title']/doc:element/doc:field[@name='value']">
|
||||
<title><xsl:value-of select="." /></title>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='contributor']/doc:element[@name='author']/doc:element/doc:field[@name='value']">
|
||||
<creator><xsl:value-of select="." /></creator>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='contributor']/doc:element[@name!='author']/doc:element/doc:field[@name='value']">
|
||||
<contributor><xsl:value-of select="." /></contributor>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='subject']/doc:element/doc:field[@name='value']">
|
||||
<subject><xsl:value-of select="." /></subject>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='description']/doc:element/doc:field[@name='value']">
|
||||
<description><xsl:value-of select="." /></description>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='description']/doc:element[@name='abstract']/doc:element/doc:field[@name='value']">
|
||||
<description><xsl:value-of select="." /></description>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='date']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<date><xsl:value-of select="." /></date>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='type']/doc:element/doc:field[@name='value']">
|
||||
<type><xsl:value-of select="." /></type>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='identifier']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<identifier><xsl:value-of select="." /></identifier>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='language']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<language><xsl:value-of select="." /></language>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='relation']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<relation><xsl:value-of select="." /></relation>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='relation']/doc:element/doc:field[@name='value']">
|
||||
<relation><xsl:value-of select="." /></relation>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='rights']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<rights><xsl:value-of select="." /></rights>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='rights']/doc:element/doc:field[@name='value']">
|
||||
<rights><xsl:value-of select="." /></rights>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='bitstreams']/doc:element[@name='bitstream']/doc:field[@name='format']">
|
||||
<format><xsl:value-of select="." /></format>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='covarage']/doc:element/doc:field[@name='value']">
|
||||
<covarage><xsl:value-of select="." /></covarage>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='covarage']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<covarage><xsl:value-of select="." /></covarage>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='publisher']/doc:element/doc:field[@name='value']">
|
||||
<publisher><xsl:value-of select="." /></publisher>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='publisher']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<publisher><xsl:value-of select="." /></publisher>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='source']/doc:element/doc:field[@name='value']">
|
||||
<source><xsl:value-of select="." /></source>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='source']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<source><xsl:value-of select="." /></source>
|
||||
</xsl:for-each>
|
||||
<xsl:if test="doc:metadata/doc:element[@name='thesis']">
|
||||
<degree>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='thesis']/doc:element[@name='name']/doc:element/doc:field[@name='value']">
|
||||
<name><xsl:value-of select="." /></name>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='thesis']/doc:element[@name='name']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<name><xsl:value-of select="." /></name>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='thesis']/doc:element[@name='level']/doc:element/doc:field[@name='value']">
|
||||
<level><xsl:value-of select="." /></level>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='thesis']/doc:element[@name='level']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<level><xsl:value-of select="." /></level>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='thesis']/doc:element[@name='discipline']/doc:element/doc:field[@name='value']">
|
||||
<discipline><xsl:value-of select="." /></discipline>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='thesis']/doc:element[@name='discipline']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<discipline><xsl:value-of select="." /></discipline>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='thesis']/doc:element[@name='grantor']/doc:element/doc:field[@name='value']">
|
||||
<grantor><xsl:value-of select="." /></grantor>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='thesis']/doc:element[@name='grantor']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<grantor><xsl:value-of select="." /></grantor>
|
||||
</xsl:for-each>
|
||||
</degree>
|
||||
</xsl:if>
|
||||
</thesis>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
63
dspace/config/modules/oai/metadataFormats/marc.xsl
Normal file
63
dspace/config/modules/oai/metadataFormats/marc.xsl
Normal file
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
|
||||
|
||||
The contents of this file are subject to the license and copyright
|
||||
detailed in the LICENSE and NOTICE files at the root of the source
|
||||
tree and available online at
|
||||
|
||||
http://www.dspace.org/license/
|
||||
Developed by DSpace @ Lyncode <dspace@lyncode.com>
|
||||
|
||||
> http://www.loc.gov/marc/bibliographic/ecbdlist.html
|
||||
|
||||
-->
|
||||
<xsl:stylesheet
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:doc="http://www.lyncode.com/xoai"
|
||||
version="1.0">
|
||||
<xsl:output omit-xml-declaration="yes" method="xml" indent="yes" />
|
||||
|
||||
<xsl:template match="/">
|
||||
<record xmlns="http://www.loc.gov/MARC21/slim"
|
||||
xmlns:dcterms="http://purl.org/dc/terms/"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd">
|
||||
<leader>am 3u</leader>
|
||||
<datafield ind2=" " ind1=" " tag="042">
|
||||
<subfield code="a">dc</subfield>
|
||||
</datafield>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='contributor']/doc:element[@name='author']/doc:element/doc:field[@name='value']">
|
||||
<datafield ind2=" " ind1=" " tag="720">
|
||||
<subfield code="a"><xsl:value-of select="." /></subfield>
|
||||
<subfield code="e">author</subfield>
|
||||
</datafield>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='date']/doc:element[@name='issued']/doc:element/doc:field[@name='value']">
|
||||
<datafield tag="260">
|
||||
<subfield code="c"><xsl:value-of select="." /></subfield>
|
||||
</datafield>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='description']/doc:element[@name='abstract']/doc:element/doc:field[@name='value']">
|
||||
<datafield tag="520">
|
||||
<subfield code="a"><xsl:value-of select="." /></subfield>
|
||||
</datafield>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='identifier']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<datafield ind1="8" tag="024">
|
||||
<subfield code="a"><xsl:value-of select="." /></subfield>
|
||||
</datafield>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='subject']/doc:element/doc:field[@name='value']">
|
||||
<datafield tag="653">
|
||||
<subfield code="a"><xsl:value-of select="." /></subfield>
|
||||
</datafield>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='title']/doc:element/doc:field[@name='value']">
|
||||
<datafield ind2="0" ind1="0" tag="245">
|
||||
<subfield code="a"><xsl:value-of select="." /></subfield>
|
||||
</datafield>
|
||||
</xsl:for-each>
|
||||
</record>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
303
dspace/config/modules/oai/metadataFormats/mets.xsl
Normal file
303
dspace/config/modules/oai/metadataFormats/mets.xsl
Normal file
@@ -0,0 +1,303 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
|
||||
|
||||
The contents of this file are subject to the license and copyright
|
||||
detailed in the LICENSE and NOTICE files at the root of the source
|
||||
tree and available online at
|
||||
|
||||
http://www.dspace.org/license/
|
||||
|
||||
Developed by DSpace @ Lyncode <dspace@lyncode.com>
|
||||
|
||||
> http://www.loc.gov/standards/mets/mets.xsd
|
||||
-->
|
||||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:doc="http://www.lyncode.com/xoai"
|
||||
xmlns:date="http://exslt.org/dates-and-times"
|
||||
extension-element-prefixes="date" version="1.0">
|
||||
|
||||
<xsl:output omit-xml-declaration="yes" method="xml" indent="yes" />
|
||||
|
||||
<xsl:template match="/">
|
||||
<mets xmlns="http://www.loc.gov/METS/" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ID="DSpace_ITEM_10400.7-31"
|
||||
TYPE="DSpace ITEM" PROFILE="DSpace METS SIP Profile 1.0"
|
||||
xsi:schemaLocation="http://www.loc.gov/METS/ http://www.loc.gov/standards/mets/mets.xsd">
|
||||
<xsl:attribute name="OBJID">
|
||||
hdl:<xsl:value-of select="doc:metadata/doc:element[@name='others']/doc:field[@name='handle']/text()"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="ID">
|
||||
DSpace_ITEM_<xsl:value-of select="translate(doc:metadata/doc:element[@name='others']/doc:field[@name='handle']/text(),'/','-')"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
<metsHdr>
|
||||
<xsl:attribute name="CREATEDATE">
|
||||
<xsl:value-of select="concat(date:format-date(date:date(), 'yyyy-MM-dd'), 'T' , date:format-date(date:time(), 'HH:mm:ss'), 'Z')"/>
|
||||
</xsl:attribute>
|
||||
<agent ROLE="CUSTODIAN" TYPE="ORGANIZATION">
|
||||
<name><xsl:value-of select="doc:metadata/doc:element[@name='repository']/doc:field[@name='name']/text()" /></name>
|
||||
</agent>
|
||||
</metsHdr>
|
||||
<dmdSec>
|
||||
<xsl:attribute name="ID">
|
||||
<xsl:value-of select="concat('DMD_', translate(doc:metadata/doc:element[@name='others']/doc:field[@name='handle']/text(), '/', '_'))" />
|
||||
</xsl:attribute>
|
||||
<mdWrap MDTYPE="MODS">
|
||||
<xmlData xmlns:mods="http://www.loc.gov/mods/v3"
|
||||
xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-1.xsd">
|
||||
<mods:mods
|
||||
xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-1.xsd">
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='contributor']/doc:element">
|
||||
<mods:name>
|
||||
<mods:role>
|
||||
<mods:roleTerm type="text"><xsl:value-of select="@name" /></mods:roleTerm>
|
||||
</mods:role>
|
||||
<mods:namePart><xsl:value-of select="doc:element/doc:field[@name='value']/text()" /></mods:namePart>
|
||||
</mods:name>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='date']/doc:element[@name='accessioned']">
|
||||
<mods:extension>
|
||||
<mods:dateAccessioned encoding="iso8601">
|
||||
<xsl:value-of select="doc:element/doc:field[@name='value']/text()" />
|
||||
</mods:dateAccessioned>
|
||||
</mods:extension>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='date']/doc:element[@name='available']">
|
||||
<mods:extension>
|
||||
<mods:dateAvailable encoding="iso8601">
|
||||
<xsl:value-of select="doc:field[@name='value']/text()" />
|
||||
</mods:dateAvailable>
|
||||
</mods:extension>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='date']/doc:element[@name='issued']">
|
||||
<mods:originInfo>
|
||||
<mods:dateIssued encoding="iso8601">
|
||||
<xsl:value-of select="doc:element/doc:field[@name='value']/text()" />
|
||||
</mods:dateIssued>
|
||||
</mods:originInfo>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='identifier']/doc:element">
|
||||
<mods:identifier>
|
||||
<xsl:attribute name="type">
|
||||
<xsl:value-of select="@name"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
<xsl:value-of select="doc:element/doc:field[@name='value']/text()" />
|
||||
</mods:identifier>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='description']/doc:element[@name='abstract']/doc:element">
|
||||
<mods:abstract>
|
||||
<xsl:value-of select="doc:field[@name='value']/text()" />
|
||||
</mods:abstract>
|
||||
</xsl:for-each>
|
||||
<mods:language>
|
||||
<mods:languageTerm authority="rfc3066"><xsl:value-of select="doc:metadata/doc:element[@name='dc']/doc:element[@name='language']/doc:element/doc:element/doc:field[@name='value']"></xsl:value-of></mods:languageTerm>
|
||||
</mods:language>
|
||||
<mods:accessCondition type="useAndReproduction"><xsl:value-of select="doc:metadata/doc:element[@name='dc']/doc:element[@name='rights']/doc:element/doc:field[@name='value']"></xsl:value-of></mods:accessCondition>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='subject']/doc:element/doc:field[@name='value']">
|
||||
<mods:subject>
|
||||
<mods:topic><xsl:value-of select="text()" /></mods:topic>
|
||||
</mods:subject>
|
||||
</xsl:for-each>
|
||||
<mods:titleInfo>
|
||||
<mods:title><xsl:value-of select="doc:metadata/doc:element[@name='dc']/doc:element[@name='title']/doc:element/doc:field[@name='value']"></xsl:value-of></mods:title>
|
||||
</mods:titleInfo>
|
||||
<mods:genre><xsl:value-of select="doc:metadata/doc:element[@name='dc']/doc:element[@name='type']/doc:element/doc:field[@name='value']"></xsl:value-of></mods:genre>
|
||||
</mods:mods>
|
||||
</xmlData>
|
||||
</mdWrap>
|
||||
</dmdSec>
|
||||
<xsl:if test="doc:metadata/doc:element[@name='license']/doc:field[@name='bin']">
|
||||
<amdSec>
|
||||
<xsl:attribute name="ID">
|
||||
<xsl:value-of select="concat('TMD_', translate(doc:metadata/doc:element[@name='others']/doc:field[@name='handle']/text(), '/', '_'))" />
|
||||
</xsl:attribute>
|
||||
<rightsMD>
|
||||
<xsl:attribute name="ID">
|
||||
<xsl:value-of select="concat('RIG_', translate(doc:metadata/doc:element[@name='others']/doc:field[@name='handle']/text(), '/', '_'))" />
|
||||
</xsl:attribute>
|
||||
<mdWrap MIMETYPE="text/plain" MDTYPE="OTHER" OTHERMDTYPE="DSpaceDepositLicense">
|
||||
<binData><xsl:value-of select="doc:metadata/doc:element[@name='license']/doc:field[@name='bin']/text()" /></binData>
|
||||
</mdWrap>
|
||||
</rightsMD>
|
||||
</amdSec>
|
||||
</xsl:if>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='bundles']/doc:element/doc:field[text()='ORIGINAL']">
|
||||
<xsl:for-each select="../doc:element[@name='bitstreams']/doc:element">
|
||||
<amdSec>
|
||||
<xsl:attribute name="ID">
|
||||
<xsl:value-of select="concat('FO_', translate(/doc:metadata/doc:element[@name='others']/doc:field[@name='handle']/text(), '/', '_'), '_', doc:field[@name='sid']/text())" />
|
||||
</xsl:attribute>
|
||||
<techMD>
|
||||
<xsl:attribute name="ID">
|
||||
<xsl:value-of select="concat('TECH_O_', translate(/doc:metadata/doc:element[@name='others']/doc:field[@name='handle']/text(), '/', '_'), '_', doc:field[@name='sid']/text())" />
|
||||
</xsl:attribute>
|
||||
<mdWrap MDTYPE="PREMIS">
|
||||
<xmlData xmlns:premis="http://www.loc.gov/standards/premis"
|
||||
xsi:schemaLocation="http://www.loc.gov/standards/premis http://www.loc.gov/standards/premis/PREMIS-v1-0.xsd">
|
||||
<premis:premis>
|
||||
<premis:object>
|
||||
<premis:objectIdentifier>
|
||||
<premis:objectIdentifierType>URL</premis:objectIdentifierType>
|
||||
<premis:objectIdentifierValue><xsl:value-of select="doc:field[@name='url']/text()" /></premis:objectIdentifierValue>
|
||||
</premis:objectIdentifier>
|
||||
<premis:objectCategory>File</premis:objectCategory>
|
||||
<premis:objectCharacteristics>
|
||||
<premis:fixity>
|
||||
<premis:messageDigestAlgorithm><xsl:value-of select="doc:field[@name='checksumAlgorithm']/text()" /></premis:messageDigestAlgorithm>
|
||||
<premis:messageDigest><xsl:value-of select="doc:field[@name='checksum']/text()" /></premis:messageDigest>
|
||||
</premis:fixity>
|
||||
<premis:size><xsl:value-of select="doc:field[@name='size']/text()" /></premis:size>
|
||||
<premis:format>
|
||||
<premis:formatDesignation>
|
||||
<premis:formatName><xsl:value-of select="doc:field[@name='format']/text()" /></premis:formatName>
|
||||
</premis:formatDesignation>
|
||||
</premis:format>
|
||||
</premis:objectCharacteristics>
|
||||
<premis:originalName><xsl:value-of select="doc:field[@name='name']/text()" /></premis:originalName>
|
||||
</premis:object>
|
||||
</premis:premis>
|
||||
</xmlData>
|
||||
</mdWrap>
|
||||
</techMD>
|
||||
</amdSec>
|
||||
</xsl:for-each>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='bundles']/doc:element/doc:field[text()='TEXT']">
|
||||
<xsl:for-each select="../doc:element[@name='bitstreams']/doc:element">
|
||||
<amdSec>
|
||||
<xsl:attribute name="ID">
|
||||
<xsl:value-of select="concat('FT_', translate(/doc:metadata/doc:element[@name='others']/doc:field[@name='handle']/text(), '/', '_'), '_', doc:field[@name='sid']/text())" />
|
||||
</xsl:attribute>
|
||||
<techMD>
|
||||
<xsl:attribute name="ID">
|
||||
<xsl:value-of select="concat('TECH_T_', translate(/doc:metadata/doc:element[@name='others']/doc:field[@name='handle']/text(), '/', '_'), '_', doc:field[@name='sid']/text())" />
|
||||
</xsl:attribute>
|
||||
<mdWrap MDTYPE="PREMIS">
|
||||
<xmlData xmlns:premis="http://www.loc.gov/standards/premis"
|
||||
xsi:schemaLocation="http://www.loc.gov/standards/premis http://www.loc.gov/standards/premis/PREMIS-v1-0.xsd">
|
||||
<premis:premis>
|
||||
<premis:object>
|
||||
<premis:objectIdentifier>
|
||||
<premis:objectIdentifierType>URL</premis:objectIdentifierType>
|
||||
<premis:objectIdentifierValue><xsl:value-of select="doc:field[@name='url']/text()" /></premis:objectIdentifierValue>
|
||||
</premis:objectIdentifier>
|
||||
<premis:objectCategory>File</premis:objectCategory>
|
||||
<premis:objectCharacteristics>
|
||||
<premis:fixity>
|
||||
<premis:messageDigestAlgorithm><xsl:value-of select="doc:field[@name='checksumAlgorithm']/text()" /></premis:messageDigestAlgorithm>
|
||||
<premis:messageDigest><xsl:value-of select="doc:field[@name='checksum']/text()" /></premis:messageDigest>
|
||||
</premis:fixity>
|
||||
<premis:size><xsl:value-of select="doc:field[@name='size']/text()" /></premis:size>
|
||||
<premis:format>
|
||||
<premis:formatDesignation>
|
||||
<premis:formatName><xsl:value-of select="doc:field[@name='format']/text()" /></premis:formatName>
|
||||
</premis:formatDesignation>
|
||||
</premis:format>
|
||||
</premis:objectCharacteristics>
|
||||
<premis:originalName><xsl:value-of select="doc:field[@name='name']/text()" /></premis:originalName>
|
||||
</premis:object>
|
||||
</premis:premis>
|
||||
</xmlData>
|
||||
</mdWrap>
|
||||
</techMD>
|
||||
</amdSec>
|
||||
</xsl:for-each>
|
||||
</xsl:for-each>
|
||||
<fileSec>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='bundles']/doc:element/doc:field[text()='ORIGINAL']">
|
||||
<fileGrp USE="ORIGINAL">
|
||||
<xsl:for-each select="../doc:element[@name='bitstreams']/doc:element">
|
||||
<file>
|
||||
<xsl:attribute name="ID">
|
||||
<xsl:value-of select="concat('BITSTREAM_ORIGINAL_', translate(/doc:metadata/doc:element[@name='others']/doc:field[@name='handle']/text(), '/', '_'), '_', doc:field[@name='sid']/text())" />
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="MIMETYPE">
|
||||
<xsl:value-of select="doc:field[@name='format']/text()" />
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="SEQ">
|
||||
<xsl:value-of select="doc:field[@name='sid']/text()" />
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="SIZE">
|
||||
<xsl:value-of select="doc:field[@name='size']/text()" />
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="CHECKSUM">
|
||||
<xsl:value-of select="doc:field[@name='checksum']/text()" />
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="CHECKSUMTYPE">
|
||||
<xsl:value-of select="doc:field[@name='checksumAlgorithm']/text()" />
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="ADMID">
|
||||
<xsl:value-of select="concat('FO_', translate(/doc:metadata/doc:element[@name='others']/doc:field[@name='handle']/text(), '/', '_'), '_', doc:field[@name='sid']/text())" />
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="GROUPID">
|
||||
<xsl:value-of select="concat('GROUP_BITSTREAM_', translate(/doc:metadata/doc:element[@name='others']/doc:field[@name='handle']/text(), '/', '_'), '_', doc:field[@name='sid']/text())" />
|
||||
</xsl:attribute>
|
||||
<FLocat LOCTYPE="URL" xlink:type="simple">
|
||||
<xsl:attribute name="xlink:href">
|
||||
<xsl:value-of select="doc:field[@name='url']/text()" />
|
||||
</xsl:attribute>
|
||||
</FLocat>
|
||||
</file>
|
||||
</xsl:for-each>
|
||||
</fileGrp>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='bundles']/doc:element/doc:field[text()='TEXT']">
|
||||
<fileGrp USE="TEXT">
|
||||
<xsl:for-each select="../doc:element[@name='bitstreams']/doc:element">
|
||||
<file>
|
||||
<xsl:attribute name="ID">
|
||||
<xsl:value-of select="concat('BITSTREAM_TEXT_', translate(/doc:metadata/doc:element[@name='others']/doc:field[@name='handle']/text(), '/', '_'), '_', doc:field[@name='sid']/text())" />
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="MIMETYPE">
|
||||
<xsl:value-of select="doc:field[@name='format']/text()" />
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="SEQ">
|
||||
<xsl:value-of select="doc:field[@name='sid']/text()" />
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="SIZE">
|
||||
<xsl:value-of select="doc:field[@name='size']/text()" />
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="CHECKSUM">
|
||||
<xsl:value-of select="doc:field[@name='checksum']/text()" />
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="CHECKSUMTYPE">
|
||||
<xsl:value-of select="doc:field[@name='checksumAlgorithm']/text()" />
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="ADMID">
|
||||
<xsl:value-of select="concat('FT_', translate(/doc:metadata/doc:element[@name='others']/doc:field[@name='handle']/text(), '/', '_'), '_', doc:field[@name='sid']/text())" />
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="GROUPID">
|
||||
<xsl:value-of select="concat('GROUP_BITSTREAM_', translate(/doc:metadata/doc:element[@name='others']/doc:field[@name='handle']/text(), '/', '_'), '_', doc:field[@name='sid']/text())" />
|
||||
</xsl:attribute>
|
||||
<FLocat LOCTYPE="URL" xlink:type="simple">
|
||||
<xsl:attribute name="xlink:href">
|
||||
<xsl:value-of select="doc:field[@name='url']/text()" />
|
||||
</xsl:attribute>
|
||||
</FLocat>
|
||||
</file>
|
||||
</xsl:for-each>
|
||||
</fileGrp>
|
||||
</xsl:for-each>
|
||||
</fileSec>
|
||||
<structMap LABEL="DSpace Object" TYPE="LOGICAL">
|
||||
<div TYPE="DSpace Object Contents">
|
||||
<xsl:attribute name="ADMID">
|
||||
<xsl:value-of select="concat('DMD_', translate(doc:metadata/doc:element[@name='others']/doc:field[@name='handle']/text(), '/', '_'))" />
|
||||
</xsl:attribute>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='bundles']/doc:element/doc:field[text()='ORIGINAL']">
|
||||
<xsl:for-each select="../doc:element[@name='bitstreams']/doc:element">
|
||||
<div TYPE="DSpace BITSTREAM">
|
||||
<fptr>
|
||||
<xsl:attribute name="FILEID">
|
||||
<xsl:value-of select="concat('BITSTREAM_ORIGINAL_', translate(/doc:metadata/doc:element[@name='others']/doc:field[@name='handle']/text(), '/', '_'), '_', doc:field[@name='sid']/text())" />
|
||||
</xsl:attribute>
|
||||
</fptr>
|
||||
</div>
|
||||
</xsl:for-each>
|
||||
</xsl:for-each>
|
||||
</div>
|
||||
</structMap>
|
||||
</mets>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
||||
84
dspace/config/modules/oai/metadataFormats/mods.xsl
Normal file
84
dspace/config/modules/oai/metadataFormats/mods.xsl
Normal file
@@ -0,0 +1,84 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
|
||||
|
||||
The contents of this file are subject to the license and copyright
|
||||
detailed in the LICENSE and NOTICE files at the root of the source
|
||||
tree and available online at
|
||||
|
||||
http://www.dspace.org/license/
|
||||
Developed by DSpace @ Lyncode <dspace@lyncode.com>
|
||||
|
||||
-->
|
||||
<xsl:stylesheet
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:doc="http://www.lyncode.com/xoai"
|
||||
version="1.0">
|
||||
<xsl:output omit-xml-declaration="yes" method="xml" indent="yes" />
|
||||
|
||||
<xsl:template match="/">
|
||||
<mods:mods xmlns:mods="http://www.loc.gov/mods/v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-1.xsd">
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='contributor']/doc:element[@name='author']/doc:element/doc:field[@name='value']">
|
||||
<mods:name>
|
||||
<mods:namePart><xsl:value-of select="." /></mods:namePart>
|
||||
</mods:name>
|
||||
</xsl:for-each>
|
||||
<xsl:if test="doc:metadata/doc:element[@name='dc']/doc:element[@name='date']/doc:element[@name='accessioned']/doc:element/doc:field[@name='value']">
|
||||
<mods:extension>
|
||||
<mods:dateAvailable encoding="iso8601">
|
||||
<xsl:value-of select="doc:metadata/doc:element[@name='dc']/doc:element[@name='date']/doc:element[@name='accessioned']/doc:element/doc:field[@name='value']/text()"></xsl:value-of>
|
||||
</mods:dateAvailable>
|
||||
</mods:extension>
|
||||
</xsl:if>
|
||||
<xsl:if test="doc:metadata/doc:element[@name='dc']/doc:element[@name='date']/doc:element[@name='available']/doc:element/doc:field[@name='value']">
|
||||
<mods:extension>
|
||||
<mods:dateAccessioned encoding="iso8601">
|
||||
<xsl:value-of select="doc:metadata/doc:element[@name='dc']/doc:element[@name='date']/doc:element[@name='available']/doc:element/doc:field[@name='value']/text()"></xsl:value-of>
|
||||
</mods:dateAccessioned>
|
||||
</mods:extension>
|
||||
</xsl:if>
|
||||
<xsl:if test="doc:metadata/doc:element[@name='dc']/doc:element[@name='date']/doc:element[@name='issued']/doc:element/doc:field[@name='value']">
|
||||
<mods:originInfo>
|
||||
<mods:dateIssued encoding="iso8601">
|
||||
<xsl:value-of select="doc:metadata/doc:element[@name='dc']/doc:element[@name='date']/doc:element[@name='issued']/doc:element/doc:field[@name='value']/text()"></xsl:value-of>
|
||||
</mods:dateIssued>
|
||||
</mods:originInfo>
|
||||
</xsl:if>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='identifier']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<mods:identifier>
|
||||
<xsl:attribute name="type">
|
||||
<xsl:value-of select="../../@name" />
|
||||
</xsl:attribute>
|
||||
<xsl:value-of select="." />
|
||||
</mods:identifier>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='description']/doc:element[@name='abstract']/doc:element/doc:field[@name='value']">
|
||||
<mods:abstract><xsl:value-of select="." /></mods:abstract>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='language']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<mods:language>
|
||||
<mods:languageTerm><xsl:value-of select="." /></mods:languageTerm>
|
||||
</mods:language>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='rights']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<mods:accessCondition type="useAndReproduction"><xsl:value-of select="." /></mods:accessCondition>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='rights']/doc:element/doc:field[@name='value']">
|
||||
<mods:accessCondition type="useAndReproduction"><xsl:value-of select="." /></mods:accessCondition>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='subject']/doc:element/doc:field[@name='value']">
|
||||
<mods:subject>
|
||||
<mods:topic><xsl:value-of select="." /></mods:topic>
|
||||
</mods:subject>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='title']/doc:element/doc:field[@name='value']">
|
||||
<mods:titleInfo>
|
||||
<mods:title><xsl:value-of select="." /></mods:title>
|
||||
</mods:titleInfo>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='type']/doc:element/doc:field[@name='value']">
|
||||
<mods:genre><xsl:value-of select="." /></mods:genre>
|
||||
</xsl:for-each>
|
||||
</mods:mods>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
91
dspace/config/modules/oai/metadataFormats/oai_dc.xsl
Normal file
91
dspace/config/modules/oai/metadataFormats/oai_dc.xsl
Normal file
@@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
|
||||
|
||||
The contents of this file are subject to the license and copyright
|
||||
detailed in the LICENSE and NOTICE files at the root of the source
|
||||
tree and available online at
|
||||
|
||||
http://www.dspace.org/license/
|
||||
Developed by DSpace @ Lyncode <dspace@lyncode.com>
|
||||
|
||||
> http://www.openarchives.org/OAI/2.0/oai_dc.xsd
|
||||
|
||||
-->
|
||||
<xsl:stylesheet
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:doc="http://www.lyncode.com/xoai"
|
||||
version="1.0">
|
||||
<xsl:output omit-xml-declaration="yes" method="xml" indent="yes" />
|
||||
|
||||
<xsl:template match="/">
|
||||
<oai_dc:dc xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/"
|
||||
xmlns:dc="http://purl.org/dc/doc:elements/1.1/"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd">
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='title']/doc:element/doc:field[@name='value']">
|
||||
<dc:title><xsl:value-of select="." /></dc:title>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='contributor']/doc:element[@name='author']/doc:element/doc:field[@name='value']">
|
||||
<dc:creator><xsl:value-of select="." /></dc:creator>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='contributor']/doc:element[@name!='author']/doc:element/doc:field[@name='value']">
|
||||
<dc:contributor><xsl:value-of select="." /></dc:contributor>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='subject']/doc:element/doc:field[@name='value']">
|
||||
<dc:subject><xsl:value-of select="." /></dc:subject>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='description']/doc:element/doc:field[@name='value']">
|
||||
<dc:description><xsl:value-of select="." /></dc:description>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='description']/doc:element[@name='abstract']/doc:element/doc:field[@name='value']">
|
||||
<dc:description><xsl:value-of select="." /></dc:description>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='date']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:date><xsl:value-of select="." /></dc:date>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='type']/doc:element/doc:field[@name='value']">
|
||||
<dc:type><xsl:value-of select="." /></dc:type>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='identifier']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:identifier><xsl:value-of select="." /></dc:identifier>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='language']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:language><xsl:value-of select="." /></dc:language>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='relation']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:relation><xsl:value-of select="." /></dc:relation>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='relation']/doc:element/doc:field[@name='value']">
|
||||
<dc:relation><xsl:value-of select="." /></dc:relation>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='rights']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:rights><xsl:value-of select="." /></dc:rights>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='rights']/doc:element/doc:field[@name='value']">
|
||||
<dc:rights><xsl:value-of select="." /></dc:rights>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='bitstreams']/doc:element[@name='bitstream']/doc:field[@name='format']">
|
||||
<dc:format><xsl:value-of select="." /></dc:format>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='covarage']/doc:element/doc:field[@name='value']">
|
||||
<dc:covarage><xsl:value-of select="." /></dc:covarage>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='covarage']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:covarage><xsl:value-of select="." /></dc:covarage>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='publisher']/doc:element/doc:field[@name='value']">
|
||||
<dc:publisher><xsl:value-of select="." /></dc:publisher>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='publisher']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:publisher><xsl:value-of select="." /></dc:publisher>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='source']/doc:element/doc:field[@name='value']">
|
||||
<dc:source><xsl:value-of select="." /></dc:source>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='source']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:source><xsl:value-of select="." /></dc:source>
|
||||
</xsl:for-each>
|
||||
</oai_dc:dc>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
110
dspace/config/modules/oai/metadataFormats/ore.xsl
Normal file
110
dspace/config/modules/oai/metadataFormats/ore.xsl
Normal file
@@ -0,0 +1,110 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
|
||||
|
||||
The contents of this file are subject to the license and copyright
|
||||
detailed in the LICENSE and NOTICE files at the root of the source
|
||||
tree and available online at
|
||||
|
||||
http://www.dspace.org/license/
|
||||
Developed by DSpace @ Lyncode <dspace@lyncode.com>
|
||||
|
||||
-->
|
||||
<xsl:stylesheet
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:doc="http://www.lyncode.com/xoai"
|
||||
version="1.0">
|
||||
<xsl:output omit-xml-declaration="yes" method="xml" indent="yes" />
|
||||
|
||||
<xsl:template match="/">
|
||||
<atom:entry xmlns:atom="http://www.w3.org/2005/Atom"
|
||||
xmlns:ore="http://www.openarchives.org/ore/terms/" xmlns:oreatom="http://www.openarchives.org/ore/atom/"
|
||||
xmlns:dcterms="http://purl.org/dc/terms/">
|
||||
<atom:id>
|
||||
<xsl:value-of select="concat(doc:metadata/doc:element[@name='dc']/doc:element[@name='identifier']/doc:element[@name='uri']/doc:element/doc:field[@name='value']/text(), '/ore.xml')"></xsl:value-of>
|
||||
</atom:id>
|
||||
<atom:link rel="alternate">
|
||||
<xsl:attribute name="href">
|
||||
<xsl:value-of select="doc:metadata/doc:element[@name='dc']/doc:element[@name='identifier']/doc:element[@name='uri']/doc:element/doc:field[@name='value']/text()"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
</atom:link>
|
||||
<atom:link rel="http://www.openarchives.org/ore/terms/describes">
|
||||
<xsl:attribute name="href">
|
||||
<xsl:value-of select="concat(doc:metadata/doc:element[@name='dc']/doc:element[@name='identifier']/doc:element[@name='uri']/doc:element/doc:field[@name='value']/text(), '/ore.xml')"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
</atom:link>
|
||||
<atom:link rel="self" type="application/atom+xml">
|
||||
<xsl:attribute name="href">
|
||||
<xsl:value-of select="concat(doc:metadata/doc:element[@name='dc']/doc:element[@name='identifier']/doc:element[@name='uri']/doc:element/doc:field[@name='value']/text(), '/ore.xml#atom')"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
</atom:link>
|
||||
<atom:published>
|
||||
<xsl:value-of select="doc:metadata/doc:element[@name='dc']/doc:element[@name='date']/doc:element[@name='available']/doc:element/doc:field[@name='value']/text()"></xsl:value-of>
|
||||
</atom:published>
|
||||
<atom:updated>
|
||||
<xsl:value-of select="doc:metadata/doc:element[@name='dc']/doc:element[@name='date']/doc:element[@name='accessioned']/doc:element/doc:field[@name='value']/text()"></xsl:value-of>
|
||||
</atom:updated>
|
||||
<atom:source>
|
||||
<atom:generator>
|
||||
<xsl:value-of select="doc:metadata/doc:element[@name='repository']/doc:field[@name='name']/text()"></xsl:value-of>
|
||||
</atom:generator>
|
||||
</atom:source>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='title']/doc:element/doc:field[@name='value']">
|
||||
<atom:title><xsl:value-of select="." /></atom:title>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='contributor']/doc:element[@name='author']/doc:element/doc:field[@name='value']">
|
||||
<atom:author><atom:name><xsl:value-of select="." /></atom:name></atom:author>
|
||||
</xsl:for-each>
|
||||
<atom:category scheme="http://www.openarchives.org/ore/terms/"
|
||||
term="http://www.openarchives.org/ore/terms/Aggregation" label="Aggregation" />
|
||||
<atom:category scheme="http://www.openarchives.org/ore/atom/modified">
|
||||
<xsl:attribute name="term">
|
||||
<xsl:value-of select="doc:metadata/doc:element[@name='dc']/doc:element[@name='date']/doc:element[@name='accessioned']/doc:element/doc:field[@name='value']/text()"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
</atom:category>
|
||||
<atom:category scheme="http://www.dspace.org/objectModel/" term="DSpaceItem" label="DSpace Item" />
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='bundles']/doc:element[@name='bundle']">
|
||||
<xsl:if test="doc:field[@name='name']/text() = 'ORIGINAL'">
|
||||
<xsl:for-each select="doc:element[@name='bitstreams']/doc:element[@name='bitstream']">
|
||||
<atom:link rel="http://www.openarchives.org/ore/terms/aggregates">
|
||||
<xsl:attribute name="href">
|
||||
<xsl:value-of select="doc:field[@name='url']/text()"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="title">
|
||||
<xsl:value-of select="doc:field[@name='name']/text()"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="type">
|
||||
<xsl:value-of select="doc:field[@name='format']/text()"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="length">
|
||||
<xsl:value-of select="doc:field[@name='size']/text()"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
</atom:link>
|
||||
</xsl:for-each>
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
<oreatom:triples>
|
||||
<rdf:Description xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<xsl:attribute name="rdf:about">
|
||||
<xsl:value-of select="concat(doc:metadata/doc:element[@name='dc']/doc:element[@name='identifier']/doc:element[@name='uri']/doc:element/doc:field[@name='value']/text(), '/ore.xml#atom')"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
<rdf:type rdf:resource="http://www.dspace.org/objectModel/DSpaceItem" />
|
||||
<dcterms:modified>
|
||||
<xsl:value-of select="doc:metadata/doc:element[@name='dc']/doc:element[@name='date']/doc:element[@name='accessioned']/doc:element/doc:field[@name='value']/text()"></xsl:value-of>
|
||||
</dcterms:modified>
|
||||
</rdf:Description>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='bundles']/doc:element[@name='bundle']/doc:element[@name='bitstreams']/doc:element[@name='bitstream']">
|
||||
<rdf:Description xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<xsl:attribute name="rdf:about">
|
||||
<xsl:value-of select="doc:field[@name='url']/text()"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
<rdf:type rdf:resource="http://www.dspace.org/objectModel/DSpaceBitstream" />
|
||||
<dcterms:description>
|
||||
<xsl:value-of select="../../doc:field[@name='name']/text()"></xsl:value-of>
|
||||
</dcterms:description>
|
||||
</rdf:Description>
|
||||
</xsl:for-each>
|
||||
</oreatom:triples>
|
||||
</atom:entry>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
345
dspace/config/modules/oai/metadataFormats/qdc.xsl
Normal file
345
dspace/config/modules/oai/metadataFormats/qdc.xsl
Normal file
@@ -0,0 +1,345 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
|
||||
|
||||
The contents of this file are subject to the license and copyright
|
||||
detailed in the LICENSE and NOTICE files at the root of the source
|
||||
tree and available online at
|
||||
|
||||
http://www.dspace.org/license/
|
||||
Developed by DSpace @ Lyncode <dspace@lyncode.com>
|
||||
|
||||
> http://www.openarchives.org/OAI/2.0/oai_dc.xsd
|
||||
|
||||
-->
|
||||
<xsl:stylesheet
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:doc="http://www.lyncode.com/xoai"
|
||||
version="1.0">
|
||||
<xsl:output omit-xml-declaration="yes" method="xml" indent="yes" />
|
||||
|
||||
<xsl:template match="/">
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='title']/doc:element/doc:field[@name='value']">
|
||||
<dc:title xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://purl.org/dc/terms/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dcterms.xsd http://purl.org/dc/elements/1.1/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dc.xsd">
|
||||
<xsl:choose>
|
||||
<xsl:when test="../../doc:element[@name='none']">
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:attribute name="xml:lang">
|
||||
<xsl:value-of select="../../doc:element/@name"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:value-of select="." />
|
||||
</dc:title>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='contributor']/doc:element[@name='author']/doc:element/doc:field[@name='value']">
|
||||
<dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://purl.org/dc/terms/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dcterms.xsd http://purl.org/dc/elements/1.1/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dc.xsd">
|
||||
<xsl:choose>
|
||||
<xsl:when test="../../doc:element[@name='none']">
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:attribute name="xml:lang">
|
||||
<xsl:value-of select="../../doc:element/@name"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:value-of select="." />
|
||||
</dc:creator>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='contributor']/doc:element[@name!='author']/doc:element/doc:field[@name='value']">
|
||||
<dc:contributor xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://purl.org/dc/terms/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dcterms.xsd http://purl.org/dc/elements/1.1/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dc.xsd">
|
||||
<xsl:choose>
|
||||
<xsl:when test="../../doc:element[@name='none']">
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:attribute name="xml:lang">
|
||||
<xsl:value-of select="../../doc:element/@name"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:value-of select="." />
|
||||
</dc:contributor>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='subject']/doc:element/doc:field[@name='value']">
|
||||
<dc:subject xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://purl.org/dc/terms/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dcterms.xsd http://purl.org/dc/elements/1.1/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dc.xsd">
|
||||
<xsl:choose>
|
||||
<xsl:when test="../../doc:element[@name='none']">
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:attribute name="xml:lang">
|
||||
<xsl:value-of select="../../doc:element/@name"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:value-of select="." />
|
||||
</dc:subject>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='description']/doc:element[@name='abstract']/doc:element/doc:field[@name='value']">
|
||||
<dcterms:abstract xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://purl.org/dc/terms/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dcterms.xsd http://purl.org/dc/elements/1.1/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dc.xsd">
|
||||
<xsl:choose>
|
||||
<xsl:when test="../../doc:element[@name='none']">
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:attribute name="xml:lang">
|
||||
<xsl:value-of select="../../doc:element/@name"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:value-of select="." />
|
||||
</dcterms:abstract>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='date']/doc:element[@name='available']/doc:element/doc:field[@name='value']">
|
||||
<dcterms:dateAccepted xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://purl.org/dc/terms/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dcterms.xsd http://purl.org/dc/elements/1.1/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dc.xsd">
|
||||
<xsl:choose>
|
||||
<xsl:when test="../../doc:element[@name='none']">
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:attribute name="xml:lang">
|
||||
<xsl:value-of select="../../doc:element/@name"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:value-of select="." />
|
||||
</dcterms:dateAccepted>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='date']/doc:element[@name='available']/doc:element/doc:field[@name='value']">
|
||||
<dcterms:available xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://purl.org/dc/terms/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dcterms.xsd http://purl.org/dc/elements/1.1/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dc.xsd">
|
||||
<xsl:choose>
|
||||
<xsl:when test="../../doc:element[@name='none']">
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:attribute name="xml:lang">
|
||||
<xsl:value-of select="../../doc:element/@name"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:value-of select="." />
|
||||
</dcterms:available>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='date']/doc:element[@name='available']/doc:element/doc:field[@name='value']">
|
||||
<dcterms:created xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://purl.org/dc/terms/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dcterms.xsd http://purl.org/dc/elements/1.1/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dc.xsd">
|
||||
<xsl:choose>
|
||||
<xsl:when test="../../doc:element[@name='none']">
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:attribute name="xml:lang">
|
||||
<xsl:value-of select="../../doc:element/@name"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:value-of select="." />
|
||||
</dcterms:created>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='date']/doc:element[@name='issued']/doc:element/doc:field[@name='value']">
|
||||
<dcterms:issued xmlns:dcterms="http://purl.org/dc/terms/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://purl.org/dc/terms/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dcterms.xsd http://purl.org/dc/elements/1.1/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dc.xsd">
|
||||
<xsl:choose>
|
||||
<xsl:when test="../../doc:element[@name='none']">
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:attribute name="xml:lang">
|
||||
<xsl:value-of select="../../doc:element/@name"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:value-of select="." />
|
||||
</dcterms:issued>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='type']/doc:element/doc:field[@name='value']">
|
||||
<dc:type xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://purl.org/dc/terms/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dcterms.xsd http://purl.org/dc/elements/1.1/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dc.xsd">
|
||||
<xsl:choose>
|
||||
<xsl:when test="../../doc:element[@name='none']">
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:attribute name="xml:lang">
|
||||
<xsl:value-of select="../../doc:element/@name"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:value-of select="." />
|
||||
</dc:type>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='identifier']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:identifier xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://purl.org/dc/terms/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dcterms.xsd http://purl.org/dc/elements/1.1/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dc.xsd">
|
||||
<xsl:choose>
|
||||
<xsl:when test="../../doc:element[@name='none']">
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:attribute name="xml:lang">
|
||||
<xsl:value-of select="../../doc:element/@name"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:value-of select="." />
|
||||
</dc:identifier>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='language']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:language xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://purl.org/dc/terms/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dcterms.xsd http://purl.org/dc/elements/1.1/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dc.xsd">
|
||||
<xsl:choose>
|
||||
<xsl:when test="../../doc:element[@name='none']">
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:attribute name="xml:lang">
|
||||
<xsl:value-of select="../../doc:element/@name"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:value-of select="." />
|
||||
</dc:language>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='relation']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:relation xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://purl.org/dc/terms/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dcterms.xsd http://purl.org/dc/elements/1.1/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dc.xsd">
|
||||
<xsl:choose>
|
||||
<xsl:when test="../../doc:element[@name='none']">
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:attribute name="xml:lang">
|
||||
<xsl:value-of select="../../doc:element/@name"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:value-of select="." />
|
||||
</dc:relation>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='relation']/doc:element/doc:field[@name='value']">
|
||||
<dc:relation xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://purl.org/dc/terms/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dcterms.xsd http://purl.org/dc/elements/1.1/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dc.xsd">
|
||||
<xsl:choose>
|
||||
<xsl:when test="../../doc:element[@name='none']">
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:attribute name="xml:lang">
|
||||
<xsl:value-of select="../../doc:element/@name"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:value-of select="." />
|
||||
</dc:relation>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='rights']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:rights xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://purl.org/dc/terms/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dcterms.xsd http://purl.org/dc/elements/1.1/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dc.xsd">
|
||||
<xsl:choose>
|
||||
<xsl:when test="../../doc:element[@name='none']">
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:attribute name="xml:lang">
|
||||
<xsl:value-of select="../../doc:element/@name"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:value-of select="." />
|
||||
</dc:rights>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='rights']/doc:element/doc:field[@name='value']">
|
||||
<dc:rights xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://purl.org/dc/terms/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dcterms.xsd http://purl.org/dc/elements/1.1/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dc.xsd">
|
||||
<xsl:choose>
|
||||
<xsl:when test="../../doc:element[@name='none']">
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:attribute name="xml:lang">
|
||||
<xsl:value-of select="../../doc:element/@name"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:value-of select="." />
|
||||
</dc:rights>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='bitstreams']/doc:element[@name='bitstream']/doc:field[@name='format']">
|
||||
<dc:format xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://purl.org/dc/terms/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dcterms.xsd http://purl.org/dc/elements/1.1/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dc.xsd">
|
||||
<xsl:choose>
|
||||
<xsl:when test="../../doc:element[@name='none']">
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:attribute name="xml:lang">
|
||||
<xsl:value-of select="../../doc:element/@name"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:value-of select="." />
|
||||
</dc:format>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='covarage']/doc:element/doc:field[@name='value']">
|
||||
<dc:covarage xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://purl.org/dc/terms/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dcterms.xsd http://purl.org/dc/elements/1.1/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dc.xsd">
|
||||
<xsl:choose>
|
||||
<xsl:when test="../../doc:element[@name='none']">
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:attribute name="xml:lang">
|
||||
<xsl:value-of select="../../doc:element/@name"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:value-of select="." />
|
||||
</dc:covarage>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='covarage']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:covarage xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://purl.org/dc/terms/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dcterms.xsd http://purl.org/dc/elements/1.1/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dc.xsd">
|
||||
<xsl:choose>
|
||||
<xsl:when test="../../doc:element[@name='none']">
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:attribute name="xml:lang">
|
||||
<xsl:value-of select="../../doc:element/@name"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:value-of select="." />
|
||||
</dc:covarage>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='publisher']/doc:element/doc:field[@name='value']">
|
||||
<dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://purl.org/dc/terms/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dcterms.xsd http://purl.org/dc/elements/1.1/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dc.xsd">
|
||||
<xsl:choose>
|
||||
<xsl:when test="../../doc:element[@name='none']">
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:attribute name="xml:lang">
|
||||
<xsl:value-of select="../../doc:element/@name"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:value-of select="." />
|
||||
</dc:publisher>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='publisher']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:publisher xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://purl.org/dc/terms/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dcterms.xsd http://purl.org/dc/elements/1.1/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dc.xsd">
|
||||
<xsl:choose>
|
||||
<xsl:when test="../../doc:element[@name='none']">
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:attribute name="xml:lang">
|
||||
<xsl:value-of select="../../doc:element/@name"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:value-of select="." />
|
||||
</dc:publisher>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='source']/doc:element/doc:field[@name='value']">
|
||||
<dc:source xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://purl.org/dc/terms/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dcterms.xsd http://purl.org/dc/elements/1.1/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dc.xsd">
|
||||
<xsl:choose>
|
||||
<xsl:when test="../../doc:element[@name='none']">
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:attribute name="xml:lang">
|
||||
<xsl:value-of select="../../doc:element/@name"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:value-of select="." />
|
||||
</dc:source>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='source']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:source xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://purl.org/dc/terms/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dcterms.xsd http://purl.org/dc/elements/1.1/ http://dublincore.org/schemas/xmls/qdc/2006/01/06/dc.xsd">
|
||||
<xsl:choose>
|
||||
<xsl:when test="../../doc:element[@name='none']">
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:attribute name="xml:lang">
|
||||
<xsl:value-of select="../../doc:element/@name"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:value-of select="." />
|
||||
</dc:source>
|
||||
</xsl:for-each>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
105
dspace/config/modules/oai/metadataFormats/rdf.xsl
Normal file
105
dspace/config/modules/oai/metadataFormats/rdf.xsl
Normal file
@@ -0,0 +1,105 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
|
||||
|
||||
The contents of this file are subject to the license and copyright
|
||||
detailed in the LICENSE and NOTICE files at the root of the source
|
||||
tree and available online at
|
||||
|
||||
http://www.dspace.org/license/
|
||||
Developed by DSpace @ Lyncode <dspace@lyncode.com>
|
||||
|
||||
-->
|
||||
<xsl:stylesheet
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:doc="http://www.lyncode.com/xoai"
|
||||
version="1.0">
|
||||
<xsl:output omit-xml-declaration="yes" method="xml" indent="yes" />
|
||||
|
||||
<xsl:template match="/">
|
||||
<rdf:RDF xmlns:rdf="http://www.openarchives.org/OAI/2.0/rdf/"
|
||||
xmlns:ow="http://www.ontoweb.org/ontology/1#" xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:ds="http://dspace.org/ds/elements/1.1/"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/rdf/ http://www.openarchives.org/OAI/2.0/rdf.xsd">
|
||||
<ow:Publication>
|
||||
<xsl:if test="doc:metadata/doc:element[@name='others']/doc:field[@name='identifier']">
|
||||
<xsl:attribute name="rdf:about">
|
||||
<xsl:value-of select="doc:metadata/doc:element[@name='others']/doc:field[@name='identifier']/text()"></xsl:value-of>
|
||||
</xsl:attribute>
|
||||
</xsl:if>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='title']/doc:element/doc:field[@name='value']">
|
||||
<dc:title><xsl:value-of select="." /></dc:title>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='contributor']/doc:element[@name='author']/doc:element/doc:field[@name='value']">
|
||||
<dc:creator><xsl:value-of select="." /></dc:creator>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='contributor']/doc:element[@name!='author']/doc:element/doc:field[@name='value']">
|
||||
<dc:contributor><xsl:value-of select="." /></dc:contributor>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='subject']/doc:element/doc:field[@name='value']">
|
||||
<dc:subject><xsl:value-of select="." /></dc:subject>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='description']/doc:element/doc:field[@name='value']">
|
||||
<dc:description><xsl:value-of select="." /></dc:description>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='description']/doc:element[@name='abstract']/doc:element/doc:field[@name='value']">
|
||||
<dc:description><xsl:value-of select="." /></dc:description>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='date']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:date><xsl:value-of select="." /></dc:date>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='type']/doc:element/doc:field[@name='value']">
|
||||
<dc:type><xsl:value-of select="." /></dc:type>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='identifier']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:identifier><xsl:value-of select="." /></dc:identifier>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='language']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:language><xsl:value-of select="." /></dc:language>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='relation']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:relation><xsl:value-of select="." /></dc:relation>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='relation']/doc:element/doc:field[@name='value']">
|
||||
<dc:relation><xsl:value-of select="." /></dc:relation>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='rights']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:rights><xsl:value-of select="." /></dc:rights>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='rights']/doc:element/doc:field[@name='value']">
|
||||
<dc:rights><xsl:value-of select="." /></dc:rights>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='bitstreams']/doc:element[@name='bitstream']/doc:field[@name='format']">
|
||||
<dc:format><xsl:value-of select="." /></dc:format>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='covarage']/doc:element/doc:field[@name='value']">
|
||||
<dc:covarage><xsl:value-of select="." /></dc:covarage>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='covarage']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:covarage><xsl:value-of select="." /></dc:covarage>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='publisher']/doc:element/doc:field[@name='value']">
|
||||
<dc:publisher><xsl:value-of select="." /></dc:publisher>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='publisher']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:publisher><xsl:value-of select="." /></dc:publisher>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='source']/doc:element/doc:field[@name='value']">
|
||||
<dc:source><xsl:value-of select="." /></dc:source>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='source']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:source><xsl:value-of select="." /></dc:source>
|
||||
</xsl:for-each>
|
||||
<xsl:if test="doc:metadata/doc:element[@name='dc']/doc:element[@name='peerreviewed']">
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='peerreviewed']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:peerreviewed><xsl:value-of select="." /></dc:peerreviewed>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='peerreviewed']/doc:element/doc:field[@name='value']">
|
||||
<dc:peerreviewed><xsl:value-of select="." /></dc:peerreviewed>
|
||||
</xsl:for-each>
|
||||
</xsl:if>
|
||||
</ow:Publication>
|
||||
</rdf:RDF>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
105
dspace/config/modules/oai/metadataFormats/uketd_dc.xsl
Normal file
105
dspace/config/modules/oai/metadataFormats/uketd_dc.xsl
Normal file
@@ -0,0 +1,105 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
|
||||
|
||||
The contents of this file are subject to the license and copyright
|
||||
detailed in the LICENSE and NOTICE files at the root of the source
|
||||
tree and available online at
|
||||
|
||||
http://www.dspace.org/license/
|
||||
Developed by DSpace @ Lyncode <dspace@lyncode.com>
|
||||
|
||||
-->
|
||||
<xsl:stylesheet
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:doc="http://www.lyncode.com/xoai"
|
||||
version="1.0">
|
||||
<xsl:output omit-xml-declaration="yes" method="xml" indent="yes" />
|
||||
|
||||
<xsl:template match="/">
|
||||
<uketd_dc:uketddc
|
||||
xmlns:uketd_dc="http://naca.central.cranfield.ac.uk/ethos-oai/2.0/"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:dcterms="http://purl.org/dc/terms/"
|
||||
xmlns:uketdterms="http://naca.central.cranfield.ac.uk/ethos-oai/terms/"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://naca.central.cranfield.ac.uk/ethos-oai/2.0/ http://naca.central.cranfield.ac.uk/ethos-oai/2.0/uketd_dc.xsd">
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='date']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:date><xsl:value-of select="." /></dc:date>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='date']/doc:element[@name='issued']/doc:element/doc:field[@name='value']">
|
||||
<dcterms:issued><xsl:value-of select="." /></dcterms:issued>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='identifier']/doc:element[@name='uri']/doc:element/doc:field[@name='value']">
|
||||
<dcterms:isReferencedBy xsi:type="dcterms:URI"><xsl:value-of select="." /></dcterms:isReferencedBy>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='description']/doc:element[@name='abstract']/doc:element/doc:field[@name='value']">
|
||||
<dcterms:abstract><xsl:value-of select="." /></dcterms:abstract>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='title']/doc:element/doc:field[@name='value']">
|
||||
<dc:title><xsl:value-of select="." /></dc:title>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='contributor']/doc:element[@name='author']/doc:element/doc:field[@name='value']">
|
||||
<dc:creator><xsl:value-of select="." /></dc:creator>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='contributor']/doc:element[@name!='author']/doc:element/doc:field[@name='value']">
|
||||
<dc:contributor><xsl:value-of select="." /></dc:contributor>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='subject']/doc:element/doc:field[@name='value']">
|
||||
<dc:subject><xsl:value-of select="." /></dc:subject>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='description']/doc:element/doc:field[@name='value']">
|
||||
<dc:description><xsl:value-of select="." /></dc:description>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='description']/doc:element[@name='abstract']/doc:element/doc:field[@name='value']">
|
||||
<dc:description><xsl:value-of select="." /></dc:description>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='type']/doc:element/doc:field[@name='value']">
|
||||
<dc:type><xsl:value-of select="." /></dc:type>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='identifier']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:identifier><xsl:value-of select="." /></dc:identifier>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='language']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:language><xsl:value-of select="." /></dc:language>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='relation']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:relation><xsl:value-of select="." /></dc:relation>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='relation']/doc:element/doc:field[@name='value']">
|
||||
<dc:relation><xsl:value-of select="." /></dc:relation>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='rights']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:rights><xsl:value-of select="." /></dc:rights>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='rights']/doc:element/doc:field[@name='value']">
|
||||
<dc:rights><xsl:value-of select="." /></dc:rights>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='bitstreams']/doc:element[@name='bitstream']/doc:field[@name='format']">
|
||||
<dc:format><xsl:value-of select="." /></dc:format>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='covarage']/doc:element/doc:field[@name='value']">
|
||||
<dc:covarage><xsl:value-of select="." /></dc:covarage>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='covarage']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:covarage><xsl:value-of select="." /></dc:covarage>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='publisher']/doc:element/doc:field[@name='value']">
|
||||
<dc:publisher><xsl:value-of select="." /></dc:publisher>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='publisher']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:publisher><xsl:value-of select="." /></dc:publisher>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='source']/doc:element/doc:field[@name='value']">
|
||||
<dc:source><xsl:value-of select="." /></dc:source>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='dc']/doc:element[@name='source']/doc:element/doc:element/doc:field[@name='value']">
|
||||
<dc:source><xsl:value-of select="." /></dc:source>
|
||||
</xsl:for-each>
|
||||
<xsl:for-each select="doc:metadata/doc:element[@name='bundles']/doc:element[@name='bundle']/doc:element[@name='bitstreams']/doc:element[@name='bitstream']">
|
||||
<dc:identifier xsi:type="dcterms:URI"><xsl:value-of select="doc:field[@name='url']/text()" /></dc:identifier>
|
||||
<uketdterms:checksum xsi:type="uketdterms:MD5"><xsl:value-of select="doc:field[@name='checksum']/text()" /></uketdterms:checksum>
|
||||
</xsl:for-each>
|
||||
</uketd_dc:uketddc>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
25
dspace/config/modules/oai/metadataFormats/xoai.xsl
Normal file
25
dspace/config/modules/oai/metadataFormats/xoai.xsl
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
|
||||
|
||||
The contents of this file are subject to the license and copyright
|
||||
detailed in the LICENSE and NOTICE files at the root of the source
|
||||
tree and available online at
|
||||
|
||||
http://www.dspace.org/license/
|
||||
|
||||
Developed by DSpace @ Lyncode <dspace@lyncode.com>
|
||||
|
||||
-->
|
||||
<xsl:stylesheet
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:doc="http://www.lyncode.com/xoai"
|
||||
version="1.0">
|
||||
<xsl:output omit-xml-declaration="yes" method="xml" indent="yes" />
|
||||
|
||||
<!-- An identity transformation to show the internal XOAI generated XML -->
|
||||
<xsl:template match="/ | @* | node()">
|
||||
<xsl:copy-of select="@* | node()">
|
||||
</xsl:copy-of>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
78
dspace/config/modules/oai/transformers/driver.xsl
Normal file
78
dspace/config/modules/oai/transformers/driver.xsl
Normal file
@@ -0,0 +1,78 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
|
||||
The contents of this file are subject to the license and copyright
|
||||
detailed in the LICENSE and NOTICE files at the root of the source
|
||||
tree and available online at
|
||||
|
||||
http://www.dspace.org/license/
|
||||
|
||||
Developed by DSpace @ Lyncode <dspace@lyncode.com>
|
||||
Following Driver Guidelines 2.0:
|
||||
- http://www.driver-support.eu/managers.html#guidelines
|
||||
|
||||
-->
|
||||
<xsl:stylesheet version="1.0"
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:doc="http://www.lyncode.com/xoai">
|
||||
<xsl:output indent="yes" method="xml" omit-xml-declaration="yes" />
|
||||
|
||||
<xsl:template match="@*|node()">
|
||||
<xsl:copy>
|
||||
<xsl:apply-templates select="@*|node()" />
|
||||
</xsl:copy>
|
||||
</xsl:template>
|
||||
|
||||
<!-- Formatting dc.date.issued -->
|
||||
<xsl:template match="/doc:metadata/doc:element[@name='dc']/doc:element[@name='date']/doc:element[@name='issued']/doc:element/doc:field/text()">
|
||||
<xsl:call-template name="formatdate">
|
||||
<xsl:with-param name="datestr" select="." />
|
||||
</xsl:call-template>
|
||||
</xsl:template>
|
||||
|
||||
<!-- Removing other dc.date.* -->
|
||||
<xsl:template match="/doc:metadata/doc:element[@name='dc']/doc:element[@name='date']/doc:element[@name!='issued']" />
|
||||
|
||||
<!-- Prefixing dc.type -->
|
||||
<xsl:template match="/doc:metadata/doc:element[@name='dc']/doc:element[@name='type']/doc:element/doc:field/text()">
|
||||
<xsl:call-template name="addPrefix">
|
||||
<xsl:with-param name="value" select="." />
|
||||
<xsl:with-param name="prefix" select="'info:eu-repo/semantics/'"></xsl:with-param>
|
||||
</xsl:call-template>
|
||||
</xsl:template>
|
||||
|
||||
<!-- Prefixing and Modifying dc.rights -->
|
||||
<!-- Removing unwanted -->
|
||||
<xsl:template match="/doc:metadata/doc:element[@name='dc']/doc:element[@name='rights']/doc:element/doc:element" />
|
||||
<!-- Replacing -->
|
||||
<xsl:template match="/doc:metadata/doc:element[@name='dc']/doc:element[@name='rights']/doc:element/doc:field/text()">
|
||||
<xsl:text>info:eu-repo/semantics/openAccess</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
|
||||
<!-- AUXILIARY TEMPLATES -->
|
||||
|
||||
<!-- dc.type prefixing -->
|
||||
<xsl:template name="addPrefix">
|
||||
<xsl:param name="value" />
|
||||
<xsl:param name="prefix" />
|
||||
<xsl:choose>
|
||||
<xsl:when test="starts-with($value, $prefix)">
|
||||
<xsl:value-of select="$value" />
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="concat($prefix, $value)" />
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<!-- Date format -->
|
||||
<xsl:template name="formatdate">
|
||||
<xsl:param name="datestr" />
|
||||
<xsl:variable name="sub">
|
||||
<xsl:value-of select="substring($datestr,1,10)" />
|
||||
</xsl:variable>
|
||||
<xsl:value-of select="$sub" />
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
91
dspace/config/modules/oai/transformers/openaire.xsl
Normal file
91
dspace/config/modules/oai/transformers/openaire.xsl
Normal file
@@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
The contents of this file are subject to the license and copyright
|
||||
detailed in the LICENSE and NOTICE files at the root of the source
|
||||
tree and available online at
|
||||
|
||||
http://www.dspace.org/license/
|
||||
|
||||
Developed by DSpace @ Lyncode <dspace@lyncode.com>
|
||||
Following OpenAIRE Guidelines 1.1:
|
||||
- http://www.openaire.eu/component/content/article/207
|
||||
|
||||
-->
|
||||
<xsl:stylesheet version="1.0"
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:doc="http://www.lyncode.com/xoai">
|
||||
<xsl:output indent="yes" method="xml" omit-xml-declaration="yes" />
|
||||
|
||||
<xsl:template match="@*|node()">
|
||||
<xsl:copy>
|
||||
<xsl:apply-templates select="@*|node()" />
|
||||
</xsl:copy>
|
||||
</xsl:template>
|
||||
|
||||
<!-- Formatting dc.date.issued -->
|
||||
<xsl:template match="/doc:metadata/doc:element[@name='dc']/doc:element[@name='date']/doc:element[@name='issued']/doc:element/doc:field/text()">
|
||||
<xsl:call-template name="formatdate">
|
||||
<xsl:with-param name="datestr" select="." />
|
||||
</xsl:call-template>
|
||||
</xsl:template>
|
||||
|
||||
<!-- Removing other dc.date.* -->
|
||||
<xsl:template match="/doc:metadata/doc:element[@name='dc']/doc:element[@name='date']/doc:element[@name!='issued']" />
|
||||
|
||||
<!-- Prefixing dc.type -->
|
||||
<xsl:template match="/doc:metadata/doc:element[@name='dc']/doc:element[@name='type']/doc:element/doc:field/text()">
|
||||
<xsl:call-template name="addPrefix">
|
||||
<xsl:with-param name="value" select="." />
|
||||
<xsl:with-param name="prefix" select="'info:eu-repo/semantics/'"></xsl:with-param>
|
||||
</xsl:call-template>
|
||||
</xsl:template>
|
||||
|
||||
<!-- Prefixing and Modifying dc.rights -->
|
||||
<!-- Removing unwanted -->
|
||||
<xsl:template match="/doc:metadata/doc:element[@name='dc']/doc:element[@name='rights']/doc:element/doc:element" />
|
||||
<!-- Replacing -->
|
||||
<xsl:template match="/doc:metadata/doc:element[@name='dc']/doc:element[@name='rights']/doc:element/doc:field/text()">
|
||||
<xsl:choose>
|
||||
<xsl:when test="contains(., 'open access')">
|
||||
<xsl:text>info:eu-repo/semantics/openAccess</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="contains(., 'openAccess')">
|
||||
<xsl:text>info:eu-repo/semantics/openAccess</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="contains(., 'restrictedAccess')">
|
||||
<xsl:text>info:eu-repo/semantics/restrictedAccess</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="contains(., 'embargoedAccess')">
|
||||
<xsl:text>info:eu-repo/semantics/embargoedAccess</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:text>info:eu-repo/semantics/restrictedAccess</xsl:text>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<!-- AUXILIARY TEMPLATES -->
|
||||
|
||||
<!-- dc.type prefixing -->
|
||||
<xsl:template name="addPrefix">
|
||||
<xsl:param name="value" />
|
||||
<xsl:param name="prefix" />
|
||||
<xsl:choose>
|
||||
<xsl:when test="starts-with($value, $prefix)">
|
||||
<xsl:value-of select="$value" />
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="concat($prefix, $value)" />
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<!-- Date format -->
|
||||
<xsl:template name="formatdate">
|
||||
<xsl:param name="datestr" />
|
||||
<xsl:variable name="sub">
|
||||
<xsl:value-of select="substring($datestr,1,10)" />
|
||||
</xsl:variable>
|
||||
<xsl:value-of select="$sub" />
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
259
dspace/config/modules/oai/xoai.xml
Normal file
259
dspace/config/modules/oai/xoai.xml
Normal file
@@ -0,0 +1,259 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
The contents of this file are subject to the license and copyright
|
||||
detailed in the LICENSE and NOTICE files at the root of the source
|
||||
tree and available online at
|
||||
|
||||
http://www.dspace.org/license/
|
||||
|
||||
Developed by DSpace @ Lyncode <dspace@lyncode.com>
|
||||
-->
|
||||
<Configuration xmlns="http://www.lyncode.com/XOAIConfiguration"
|
||||
identation="false" maxListIdentifiersSize="100" maxListRecordsSize="100"
|
||||
maxListSetsSize="100" stylesheet="static/style.xsl">
|
||||
|
||||
<Contexts>
|
||||
<Context baseurl="request">
|
||||
<Format refid="oaidc" />
|
||||
<Format refid="mets" />
|
||||
<Format refid="xoai" />
|
||||
<Format refid="didl" />
|
||||
<Format refid="dim" />
|
||||
<Format refid="ore" />
|
||||
<Format refid="rdf" />
|
||||
<Format refid="etdms" />
|
||||
<Format refid="mods" />
|
||||
<Format refid="qdc" />
|
||||
<Format refid="marc" />
|
||||
<Format refid="uketd_dc" />
|
||||
</Context>
|
||||
|
||||
<!--
|
||||
Driver Guidelines:
|
||||
|
||||
- http://www.driver-support.eu/documents/DRIVER_Guidelines_v2_Final_2008-11-13.pdf
|
||||
|
||||
Page 57 - 58
|
||||
-->
|
||||
<Context baseurl="driver">
|
||||
<!-- Date format, field prefixes, etc are ensured by the transformer -->
|
||||
<Transformer refid="driverTransformer"/>
|
||||
<!-- Title : Mandatory -->
|
||||
<Filter refid="titleexistsFilter" />
|
||||
<!-- Author : Mandatory -->
|
||||
<Filter refid="authorexistsFilter"/>
|
||||
<!-- Possible Document Type -->
|
||||
<Filter refid="driverdocumenttypeFilter"/>
|
||||
<!-- dc.rights must contain openAccess token -->
|
||||
<Filter refid="driveraccessFilter"/>
|
||||
<!-- Open Access (Downloadable) -->
|
||||
<Filter refid="bitstreamaccessFilter"/>
|
||||
<!-- Just an alias, if fact it returns all items within the driver context -->
|
||||
<Set refid="driverSet" />
|
||||
<!-- Metadata Formats -->
|
||||
<Format refid="oaidc"/>
|
||||
<Format refid="mets" />
|
||||
<Format refid="didl" />
|
||||
</Context>
|
||||
|
||||
<!--
|
||||
OpenAIRE Guidelines 1.1:
|
||||
|
||||
- http://www.openaire.eu/en/component/attachments/download/79%E2%8C%A9=en
|
||||
|
||||
There is a limitation over the embargoedEndDate parameter:
|
||||
|
||||
- Predefined DSpace fields don't allow to set this up with a default.
|
||||
-->
|
||||
<Context baseurl="openaire">
|
||||
<!-- Date format, field prefixes, etc are ensured by the transformer -->
|
||||
<Transformer refid="openaireTransformer" />
|
||||
<!-- Title : Mandatory -->
|
||||
<Filter refid="titleexistsFilter" />
|
||||
<!-- Author : Mandatory -->
|
||||
<Filter refid="authorexistsFilter"/>
|
||||
<!-- Possible Document Type (same as Driver)-->
|
||||
<Filter refid="driverdocumenttypeFilter"/>
|
||||
<!-- dc.relation must has the specified prefix -->
|
||||
<Filter refid="openairerelationFilter" />
|
||||
<!-- Just an alias, if fact it returns all items within the driver context -->
|
||||
<Set refid="openaireSet" />
|
||||
<!-- Metadata Formats -->
|
||||
<Format refid="oaidc" />
|
||||
<Format refid="mets" />
|
||||
</Context>
|
||||
</Contexts>
|
||||
|
||||
|
||||
<Formats>
|
||||
<Format id="oaidc">
|
||||
<Prefix>oai_dc</Prefix>
|
||||
<XSLT>metadataFormats/oai_dc.xsl</XSLT>
|
||||
<Namespace>http://www.openarchives.org/OAI/2.0/oai_dc/</Namespace>
|
||||
<SchemaLocation>http://www.openarchives.org/OAI/2.0/oai_dc.xsd</SchemaLocation>
|
||||
</Format>
|
||||
<Format id="mets">
|
||||
<Prefix>mets</Prefix>
|
||||
<XSLT>metadataFormats/mets.xsl</XSLT>
|
||||
<Namespace>http://www.loc.gov/METS/</Namespace>
|
||||
<SchemaLocation>http://www.loc.gov/standards/mets/mets.xsd</SchemaLocation>
|
||||
</Format>
|
||||
<!-- Shows the XOAI internal generated XML -->
|
||||
<Format id="xoai">
|
||||
<Prefix>xoai</Prefix>
|
||||
<XSLT>metadataFormats/xoai.xsl</XSLT>
|
||||
<Namespace>http://www.lyncode.com/xoai</Namespace>
|
||||
<SchemaLocation>http://www.lyncode.com/schemas/xoai.xsd</SchemaLocation>
|
||||
</Format>
|
||||
<Format id="didl">
|
||||
<Prefix>didl</Prefix>
|
||||
<XSLT>metadataFormats/didl.xsl</XSLT>
|
||||
<Namespace>urn:mpeg:mpeg21:2002:02-DIDL-NS</Namespace>
|
||||
<SchemaLocation>http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-21_schema_files/did/didl.xsd</SchemaLocation>
|
||||
</Format>
|
||||
<Format id="dim">
|
||||
<Prefix>dim</Prefix>
|
||||
<XSLT>metadataFormats/dim.xsl</XSLT>
|
||||
<Namespace>http://www.dspace.org/xmlns/dspace/dim</Namespace>
|
||||
<SchemaLocation>http://www.dspace.org/schema/dim.xsd</SchemaLocation>
|
||||
</Format>
|
||||
<Format id="ore">
|
||||
<Prefix>ore</Prefix>
|
||||
<XSLT>metadataFormats/ore.xsl</XSLT>
|
||||
<Namespace>http://www.w3.org/2005/Atom</Namespace>
|
||||
<SchemaLocation>http://tweety.lanl.gov/public/schemas/2008-06/atom-tron.sch</SchemaLocation>
|
||||
</Format>
|
||||
<Format id="rdf">
|
||||
<Prefix>rdf</Prefix>
|
||||
<XSLT>metadataFormats/rdf.xsl</XSLT>
|
||||
<Namespace>http://www.openarchives.org/OAI/2.0/rdf/</Namespace>
|
||||
<SchemaLocation>http://www.openarchives.org/OAI/2.0/rdf.xsd</SchemaLocation>
|
||||
</Format>
|
||||
<Format id="etdms">
|
||||
<Prefix>etdms</Prefix>
|
||||
<XSLT>metadataFormats/etdms.xsl</XSLT>
|
||||
<Namespace>http://www.ndltd.org/standards/metadata/etdms/1.0/</Namespace>
|
||||
<SchemaLocation>http://www.ndltd.org/standards/metadata/etdms/1.0/etdms.xsd</SchemaLocation>
|
||||
</Format>
|
||||
<Format id="mods">
|
||||
<Prefix>mods</Prefix>
|
||||
<XSLT>metadataFormats/mods.xsl</XSLT>
|
||||
<Namespace>http://www.loc.gov/mods/v3</Namespace>
|
||||
<SchemaLocation>http://www.loc.gov/standards/mods/v3/mods-3-1.xsd</SchemaLocation>
|
||||
</Format>
|
||||
<Format id="qdc">
|
||||
<Prefix>qdc</Prefix>
|
||||
<XSLT>metadataFormats/qdc.xsl</XSLT>
|
||||
<Namespace>http://purl.org/dc/terms/</Namespace>
|
||||
<SchemaLocation>http://dublincore.org/schemas/xmls/qdc/2006/01/06/dcterms.xsd</SchemaLocation>
|
||||
</Format>
|
||||
<Format id="marc">
|
||||
<Prefix>marc</Prefix>
|
||||
<XSLT>metadataFormats/marc.xsl</XSLT>
|
||||
<Namespace>http://www.loc.gov/MARC21/slim</Namespace>
|
||||
<SchemaLocation>http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd</SchemaLocation>
|
||||
</Format>
|
||||
<Format id="uketd_dc">
|
||||
<Prefix>uketd_dc</Prefix>
|
||||
<XSLT>metadataFormats/uketd_dc.xsl</XSLT>
|
||||
<Namespace>http://naca.central.cranfield.ac.uk/ethos-oai/2.0/</Namespace>
|
||||
<SchemaLocation>http://naca.central.cranfield.ac.uk/ethos-oai/2.0/uketd_dc.xsd</SchemaLocation>
|
||||
</Format>
|
||||
</Formats>
|
||||
|
||||
<Transformers>
|
||||
<Transformer id="driverTransformer">
|
||||
<XSLT>transformers/driver.xsl</XSLT>
|
||||
</Transformer>
|
||||
<Transformer id="openaireTransformer">
|
||||
<XSLT>transformers/openaire.xsl</XSLT>
|
||||
</Transformer>
|
||||
</Transformers>
|
||||
|
||||
|
||||
<Filters>
|
||||
<Filter id="authorexistsFilter">
|
||||
<Class>org.dspace.xoai.filter.DSpaceMetadataExistsFilter</Class>
|
||||
<Parameter key="field">
|
||||
<Value>dc.contributor.author</Value>
|
||||
</Parameter>
|
||||
</Filter>
|
||||
|
||||
<Filter id="titleexistsFilter">
|
||||
<Class>org.dspace.xoai.filter.DSpaceMetadataExistsFilter</Class>
|
||||
<Parameter key="field">
|
||||
<Value>dc.title</Value>
|
||||
</Parameter>
|
||||
</Filter>
|
||||
|
||||
<Filter id="driverdocumenttypeFilter">
|
||||
<Class>org.dspace.xoai.filter.DSpaceAtLeastOneMetadataFilter</Class>
|
||||
<Parameter key="field">
|
||||
<Value>dc.type</Value>
|
||||
</Parameter>
|
||||
<Parameter key="operator">
|
||||
<Value>ends_with</Value>
|
||||
</Parameter>
|
||||
<Parameter key="value">
|
||||
<Value>article</Value>
|
||||
<Value>bachelorThesis</Value>
|
||||
<Value>masterThesis</Value>
|
||||
<Value>doctoralThesis</Value>
|
||||
<Value>book</Value>
|
||||
<Value>bookPart</Value>
|
||||
<Value>review</Value>
|
||||
<Value>conferenceObject</Value>
|
||||
<Value>lecture</Value>
|
||||
<Value>workingPaper</Value>
|
||||
<Value>preprint</Value>
|
||||
<Value>report</Value>
|
||||
<Value>annotation</Value>
|
||||
<Value>contributionToPeriodical</Value>
|
||||
<Value>patent</Value>
|
||||
<Value>other</Value>
|
||||
</Parameter>
|
||||
</Filter>
|
||||
<Filter id="driveraccessFilter">
|
||||
<Class>org.dspace.xoai.filter.DSpaceAtLeastOneMetadataFilter</Class>
|
||||
<Parameter key="field">
|
||||
<Value>dc.rights</Value>
|
||||
</Parameter>
|
||||
<Parameter key="operator">
|
||||
<Value>contains</Value>
|
||||
</Parameter>
|
||||
<Parameter key="value">
|
||||
<Value>open access</Value>
|
||||
<Value>openAccess</Value>
|
||||
</Parameter>
|
||||
</Filter>
|
||||
<Filter id="bitstreamaccessFilter">
|
||||
<Class>org.dspace.xoai.filter.DSpaceAuthorizationFilter</Class>
|
||||
</Filter>
|
||||
<Filter id="openairerelationFilter">
|
||||
<Class>org.dspace.xoai.filter.DSpaceAtLeastOneMetadataFilter</Class>
|
||||
<Parameter key="field">
|
||||
<Value>dc.relation</Value>
|
||||
</Parameter>
|
||||
<Parameter key="operator">
|
||||
<Value>starts_with</Value>
|
||||
</Parameter>
|
||||
<Parameter key="value">
|
||||
<Value>info:eurepo/grantAgreement/EC/FP</Value>
|
||||
</Parameter>
|
||||
</Filter>
|
||||
</Filters>
|
||||
|
||||
<Sets>
|
||||
<Set id="driverSet">
|
||||
<Pattern>driver</Pattern>
|
||||
<Name>Open Access DRIVERset</Name>
|
||||
<!-- Just an alias -->
|
||||
</Set>
|
||||
<Set id="openaireSet">
|
||||
<Pattern>ec_fundedresources</Pattern>
|
||||
<Name>EC_fundedresources set</Name>
|
||||
<!-- Just an alias -->
|
||||
</Set>
|
||||
</Sets>
|
||||
</Configuration>
|
||||
@@ -1,52 +0,0 @@
|
||||
###########################################################################
|
||||
# REMEMBER: ONLY UPDATE THE VERSION IN dspace/config/templates
|
||||
# AND THEN RUN dspace/bin/install-configs!
|
||||
# DO NOT EDIT THE 'LIVE' VERSION!
|
||||
###########################################################################
|
||||
|
||||
# OAICat Configuration file - see OAICat documentation for details
|
||||
|
||||
# Text surrounded by two '${' and '}' symbols is replaced with the corresponding
|
||||
# property from dspace.cfg. For example:
|
||||
#
|
||||
# ${dspace.url}
|
||||
#
|
||||
# would be replaced with the dspace.url property in dspace.cfg on Maven compilation
|
||||
|
||||
AbstractCatalog.oaiCatalogClassName=org.dspace.app.oai.DSpaceOAICatalog
|
||||
AbstractCatalog.recordFactoryClassName=org.dspace.app.oai.DSpaceRecordFactory
|
||||
AbstractCatalog.secondsToLive=3600
|
||||
|
||||
AbstractCatalog.granularity=YYYY-MM-DDThh:mm:ssZ
|
||||
|
||||
# Custom Identify response values
|
||||
Identify.repositoryName=${dspace.name}
|
||||
Identify.adminEmail=${mail.admin}
|
||||
Identify.earliestDatestamp=2001-01-01T00:00:00Z
|
||||
Identify.deletedRecord=persistent
|
||||
|
||||
# List the supported metadataPrefixes along with the class that performs the associated crosswalk
|
||||
#Crosswalks.didl=org.dspace.app.oai.DIDLCrosswalk
|
||||
Crosswalks.mets=org.dspace.app.oai.METSCrosswalk
|
||||
Crosswalks.oai_dc=org.dspace.app.oai.OAIDCCrosswalk
|
||||
Crosswalks.rdf=org.dspace.app.oai.RDFCrosswalk
|
||||
#Crosswalks.uketd_dc=org.dspace.app.oai.UKETDDCCrosswalk
|
||||
|
||||
# The following OAI crosswalks use crosswalk plugins defined in dspace.cfg.
|
||||
# The metadataPrefixes must match the name of the plugin
|
||||
# for interface org.dspace.content.crosswalk.DisseminationCrosswalk
|
||||
# (e.g. "ore" matches the DisseminationCrosswalk of that name in dspace.cfg)
|
||||
Crosswalks.ore=org.dspace.app.oai.PluginCrosswalk
|
||||
# Uncomment any of the below plugins to enable other harvestable metadata
|
||||
# formats. Remember to also check the corresponding DisseminationCrosswalk
|
||||
# settings in your dspace.cfg file.
|
||||
# Crosswalks.mods=org.dspace.app.oai.PluginCrosswalk
|
||||
# Crosswalks.mets=org.dspace.app.oai.PluginCrosswalk
|
||||
# Crosswalks.qdc=org.dspace.app.oai.PluginCrosswalk
|
||||
# Crosswalks.dim=org.dspace.app.oai.PluginCrosswalk
|
||||
# Crosswalks.marc=org.dspace.app.oai.PluginCrosswalk
|
||||
|
||||
# XSLT stylesheet to transform OAI-PMH XML results in web browser to
|
||||
# human-readable and browsable HTML pages
|
||||
OAIHandler.styleSheet=/oai/oai2.xsl
|
||||
|
||||
@@ -1,101 +1,131 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.dspace.modules</groupId>
|
||||
<artifactId>oai</artifactId>
|
||||
<packaging>war</packaging>
|
||||
<name>DSpace OAI :: Web Application</name>
|
||||
<description>
|
||||
DSpace OAI Service Provider Web Application
|
||||
</description>
|
||||
<?xml version="1.0"?>
|
||||
<project
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>modules</artifactId>
|
||||
<groupId>org.dspace</groupId>
|
||||
<version>3.0-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
<groupId>org.dspace.modules</groupId>
|
||||
<artifactId>oai</artifactId>
|
||||
<packaging>war</packaging>
|
||||
<name>DSpace OAI 2.0 :: Web Application</name>
|
||||
<url>http://www.lyncode.com</url>
|
||||
<description>XOAI Interface</description>
|
||||
|
||||
<!--
|
||||
A Parent POM that Maven inherits DSpace Default
|
||||
POM atrributes from.
|
||||
-->
|
||||
<parent>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>modules</artifactId>
|
||||
<version>3.0-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<configuration>
|
||||
<archiveClasses>false</archiveClasses>
|
||||
<webResources>
|
||||
<resource>
|
||||
<filtering>true</filtering>
|
||||
<directory>${basedir}/src/main/webapp</directory>
|
||||
<includes>
|
||||
<include>WEB-INF/web.xml</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</webResources>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>prepare-package</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<configuration>
|
||||
<archiveClasses>false</archiveClasses>
|
||||
<webResources>
|
||||
<resource>
|
||||
<filtering>true</filtering>
|
||||
<directory>${basedir}/src/main/webapp</directory>
|
||||
<includes>
|
||||
<include>WEB-INF/web.xml</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</webResources>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>prepare-package</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<profiles>
|
||||
<profile>
|
||||
<activation>
|
||||
<property>
|
||||
<name>dspace.config</name>
|
||||
</property>
|
||||
</activation>
|
||||
<build>
|
||||
<filters>
|
||||
<filter>${dspace.config}</filter>
|
||||
</filters>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>oracle-support</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>db.name</name>
|
||||
<value>oracle</value>
|
||||
</property>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.oracle</groupId>
|
||||
<artifactId>ojdbc6</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>postgres-support</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>!db.name</name>
|
||||
</property>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-oai-webapp</artifactId>
|
||||
<type>war</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-oai-api</artifactId>
|
||||
<version>3.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<version>1.5.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.solr</groupId>
|
||||
<artifactId>solr-core</artifactId>
|
||||
<version>3.3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-jdk14</artifactId>
|
||||
<version>1.5.6</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>postgres-support</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>!db.name</name>
|
||||
</property>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>oracle-support</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>db.name</name>
|
||||
<value>oracle</value>
|
||||
</property>
|
||||
</activation>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.oracle</groupId>
|
||||
<artifactId>ojdbc6</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
</profiles>
|
||||
<developers>
|
||||
<developer>
|
||||
<id>lyncode</id>
|
||||
<email>dspace@lyncode.com</email>
|
||||
<name>DSpace @ Lyncode</name>
|
||||
<url>http://www.lyncode.com</url>
|
||||
</developer>
|
||||
</developers>
|
||||
</project>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.dspace.modules</groupId>
|
||||
<artifactId>additions</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-oai-webapp</artifactId>
|
||||
<type>war</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-oai-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -52,15 +52,6 @@
|
||||
<module>lni</module>
|
||||
</modules>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>dspace-oai</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<modules>
|
||||
<module>oai</module>
|
||||
</modules>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>dspace-jspui</id>
|
||||
<activation>
|
||||
@@ -97,5 +88,14 @@
|
||||
<module>solr</module>
|
||||
</modules>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>dspace-xoai</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<modules>
|
||||
<module>oai</module>
|
||||
</modules>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
|
||||
@@ -84,5 +84,16 @@
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<!-- Don't know how to add artifacts to dspace lib -->
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>dspace-oai-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<version>2.3</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
31
dspace/solr/oai/conf/admin-extra.html
Normal file
31
dspace/solr/oai/conf/admin-extra.html
Normal file
@@ -0,0 +1,31 @@
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You 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.
|
||||
-->
|
||||
|
||||
<!-- The content of this page will be statically included into the top
|
||||
of the admin page. Uncomment this as an example to see there the content
|
||||
will show up.
|
||||
|
||||
<hr>
|
||||
<i>This line will appear before the first table</i>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
This row will be appended to the end of the first table
|
||||
</td>
|
||||
</tr>
|
||||
<hr>
|
||||
|
||||
-->
|
||||
36
dspace/solr/oai/conf/elevate.xml
Normal file
36
dspace/solr/oai/conf/elevate.xml
Normal file
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You 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.
|
||||
-->
|
||||
|
||||
<!-- If this file is found in the config directory, it will only be
|
||||
loaded once at startup. If it is found in Solr's data
|
||||
directory, it will be re-loaded every commit.
|
||||
-->
|
||||
|
||||
<elevate>
|
||||
<query text="foo bar">
|
||||
<doc id="1" />
|
||||
<doc id="2" />
|
||||
<doc id="3" />
|
||||
</query>
|
||||
|
||||
<query text="ipod">
|
||||
<doc id="MA147LL/A" /> <!-- put the actual ipod at the top -->
|
||||
<doc id="IW-02" exclude="true" /> <!-- exclude this cable -->
|
||||
</query>
|
||||
|
||||
</elevate>
|
||||
21
dspace/solr/oai/conf/protwords.txt
Normal file
21
dspace/solr/oai/conf/protwords.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
# The ASF licenses this file to You 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.
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
# Use a protected word file to protect against the stemmer reducing two
|
||||
# unrelated words to the same base word.
|
||||
|
||||
# Some non-words that normally won't be encountered,
|
||||
# just to test that they won't be stemmed.
|
||||
dontstems
|
||||
zwhacky
|
||||
|
||||
185
dspace/solr/oai/conf/schema.xml
Normal file
185
dspace/solr/oai/conf/schema.xml
Normal file
@@ -0,0 +1,185 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<schema name="xoai" version="1.2">
|
||||
<types>
|
||||
<fieldType name="string" class="solr.StrField" sortMissingLast="true" omitNorms="true"/>
|
||||
<fieldType name="boolean" class="solr.BoolField" sortMissingLast="true" omitNorms="true"/>
|
||||
<fieldtype name="binary" class="solr.BinaryField"/>
|
||||
<fieldType name="int" class="solr.TrieIntField" precisionStep="0" omitNorms="true" positionIncrementGap="0"/>
|
||||
<fieldType name="float" class="solr.TrieFloatField" precisionStep="0" omitNorms="true" positionIncrementGap="0"/>
|
||||
<fieldType name="long" class="solr.TrieLongField" precisionStep="0" omitNorms="true" positionIncrementGap="0"/>
|
||||
<fieldType name="double" class="solr.TrieDoubleField" precisionStep="0" omitNorms="true" positionIncrementGap="0"/>
|
||||
<fieldType name="tint" class="solr.TrieIntField" precisionStep="8" omitNorms="true" positionIncrementGap="0"/>
|
||||
<fieldType name="tfloat" class="solr.TrieFloatField" precisionStep="8" omitNorms="true" positionIncrementGap="0"/>
|
||||
<fieldType name="tlong" class="solr.TrieLongField" precisionStep="8" omitNorms="true" positionIncrementGap="0"/>
|
||||
<fieldType name="tdouble" class="solr.TrieDoubleField" precisionStep="8" omitNorms="true" positionIncrementGap="0"/>
|
||||
<fieldType name="date" class="solr.TrieDateField" omitNorms="true" precisionStep="0" positionIncrementGap="0"/>
|
||||
<fieldType name="tdate" class="solr.TrieDateField" omitNorms="true" precisionStep="6" positionIncrementGap="0"/>
|
||||
<fieldType name="pint" class="solr.IntField" omitNorms="true"/>
|
||||
<fieldType name="plong" class="solr.LongField" omitNorms="true"/>
|
||||
<fieldType name="pfloat" class="solr.FloatField" omitNorms="true"/>
|
||||
<fieldType name="pdouble" class="solr.DoubleField" omitNorms="true"/>
|
||||
<fieldType name="pdate" class="solr.DateField" sortMissingLast="true" omitNorms="true"/>
|
||||
<fieldType name="sint" class="solr.SortableIntField" sortMissingLast="true" omitNorms="true"/>
|
||||
<fieldType name="slong" class="solr.SortableLongField" sortMissingLast="true" omitNorms="true"/>
|
||||
<fieldType name="sfloat" class="solr.SortableFloatField" sortMissingLast="true" omitNorms="true"/>
|
||||
<fieldType name="sdouble" class="solr.SortableDoubleField" sortMissingLast="true" omitNorms="true"/>
|
||||
<fieldType name="random" class="solr.RandomSortField" indexed="true" />
|
||||
|
||||
<fieldType name="text_ws" class="solr.TextField" positionIncrementGap="100">
|
||||
<analyzer>
|
||||
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
|
||||
</analyzer>
|
||||
</fieldType>
|
||||
<fieldType name="text" class="solr.TextField" positionIncrementGap="100">
|
||||
<analyzer type="index">
|
||||
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
|
||||
<filter class="solr.StopFilterFactory"
|
||||
ignoreCase="true"
|
||||
words="stopwords.txt"
|
||||
enablePositionIncrements="true"
|
||||
/>
|
||||
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="1"/>
|
||||
<filter class="solr.LowerCaseFilterFactory"/>
|
||||
<filter class="solr.SnowballPorterFilterFactory" language="English" protected="protwords.txt"/>
|
||||
</analyzer>
|
||||
<analyzer type="query">
|
||||
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
|
||||
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
|
||||
<filter class="solr.StopFilterFactory"
|
||||
ignoreCase="true"
|
||||
words="stopwords.txt"
|
||||
enablePositionIncrements="true"
|
||||
/>
|
||||
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="1"/>
|
||||
<filter class="solr.LowerCaseFilterFactory"/>
|
||||
<filter class="solr.SnowballPorterFilterFactory" language="English" protected="protwords.txt"/>
|
||||
</analyzer>
|
||||
</fieldType>
|
||||
<fieldType name="textTight" class="solr.TextField" positionIncrementGap="100" >
|
||||
<analyzer>
|
||||
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
|
||||
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="false"/>
|
||||
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt"/>
|
||||
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="0" generateNumberParts="0" catenateWords="1" catenateNumbers="1" catenateAll="0"/>
|
||||
<filter class="solr.LowerCaseFilterFactory"/>
|
||||
<filter class="solr.SnowballPorterFilterFactory" language="English" protected="protwords.txt"/>
|
||||
<!-- this filter can remove any duplicate tokens that appear at the same position - sometimes
|
||||
possible with WordDelimiterFilter in conjuncton with stemming. -->
|
||||
<filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
|
||||
</analyzer>
|
||||
</fieldType>
|
||||
<fieldType name="textgen" class="solr.TextField" positionIncrementGap="100">
|
||||
<analyzer type="index">
|
||||
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
|
||||
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
|
||||
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="0"/>
|
||||
<filter class="solr.LowerCaseFilterFactory"/>
|
||||
</analyzer>
|
||||
<analyzer type="query">
|
||||
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
|
||||
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
|
||||
<filter class="solr.StopFilterFactory"
|
||||
ignoreCase="true"
|
||||
words="stopwords.txt"
|
||||
enablePositionIncrements="true"
|
||||
/>
|
||||
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="0"/>
|
||||
<filter class="solr.LowerCaseFilterFactory"/>
|
||||
</analyzer>
|
||||
</fieldType>
|
||||
<fieldType name="text_rev" class="solr.TextField" positionIncrementGap="100">
|
||||
<analyzer type="index">
|
||||
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
|
||||
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
|
||||
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="0"/>
|
||||
<filter class="solr.LowerCaseFilterFactory"/>
|
||||
<filter class="solr.ReversedWildcardFilterFactory" withOriginal="true"
|
||||
maxPosAsterisk="3" maxPosQuestion="2" maxFractionAsterisk="0.33"/>
|
||||
</analyzer>
|
||||
<analyzer type="query">
|
||||
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
|
||||
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
|
||||
<filter class="solr.StopFilterFactory"
|
||||
ignoreCase="true"
|
||||
words="stopwords.txt"
|
||||
enablePositionIncrements="true"
|
||||
/>
|
||||
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="0"/>
|
||||
<filter class="solr.LowerCaseFilterFactory"/>
|
||||
</analyzer>
|
||||
</fieldType>
|
||||
<fieldType name="alphaOnlySort" class="solr.TextField" sortMissingLast="true" omitNorms="true">
|
||||
<analyzer>
|
||||
<tokenizer class="solr.KeywordTokenizerFactory"/>
|
||||
<filter class="solr.LowerCaseFilterFactory" />
|
||||
<filter class="solr.TrimFilterFactory" />
|
||||
<filter class="solr.PatternReplaceFilterFactory"
|
||||
pattern="([^a-z])" replacement="" replace="all"
|
||||
/>
|
||||
</analyzer>
|
||||
</fieldType>
|
||||
|
||||
<fieldtype name="phonetic" stored="false" indexed="true" class="solr.TextField" >
|
||||
<analyzer>
|
||||
<tokenizer class="solr.StandardTokenizerFactory"/>
|
||||
<filter class="solr.DoubleMetaphoneFilterFactory" inject="false"/>
|
||||
</analyzer>
|
||||
</fieldtype>
|
||||
|
||||
<fieldtype name="payloads" stored="false" indexed="true" class="solr.TextField" >
|
||||
<analyzer>
|
||||
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
|
||||
<filter class="solr.DelimitedPayloadTokenFilterFactory" encoder="float"/>
|
||||
</analyzer>
|
||||
</fieldtype>
|
||||
<fieldType name="lowercase" class="solr.TextField" positionIncrementGap="100">
|
||||
<analyzer>
|
||||
<tokenizer class="solr.KeywordTokenizerFactory"/>
|
||||
<filter class="solr.LowerCaseFilterFactory" />
|
||||
</analyzer>
|
||||
</fieldType>
|
||||
<fieldtype name="ignored" stored="false" indexed="false" multiValued="true" class="solr.StrField" />
|
||||
</types>
|
||||
|
||||
|
||||
<fields>
|
||||
<!-- Item always present information -->
|
||||
<field name="item.id" type="int" indexed="true" stored="true" multiValued="false" />
|
||||
<field name="item.public" type="boolean" indexed="true" stored="true" multiValued="false" />
|
||||
<field name="item.handle" type="string" indexed="true" stored="true" multiValued="false" />
|
||||
<field name="item.collections" type="string" indexed="true" stored="true" multiValued="true" />
|
||||
<field name="item.communities" type="string" indexed="true" stored="true" multiValued="true" />
|
||||
<field name="item.lastmodified" type="date" indexed="true" stored="true" multiValued="false" />
|
||||
<field name="item.submitter" type="string" indexed="true" stored="true" multiValued="false" />
|
||||
<field name="item.deleted" type="boolean" indexed="true" stored="true" multiValued="false" />
|
||||
|
||||
<!-- Item compiled -->
|
||||
<field name="item.compile" type="string" indexed="false" stored="true" multiValued="false" />
|
||||
|
||||
<!-- Item metadata -->
|
||||
<dynamicField name="metadata.*" type="string" indexed="true" stored="true" multiValued="true" />
|
||||
|
||||
<!-- Dynamic fields (not used by default) -->
|
||||
<dynamicField name="*_i" type="int" indexed="true" stored="true"/>
|
||||
<dynamicField name="*_s" type="string" indexed="true" stored="true"/>
|
||||
<dynamicField name="*_l" type="long" indexed="true" stored="true"/>
|
||||
<dynamicField name="*_t" type="text" indexed="true" stored="true"/>
|
||||
<dynamicField name="*_b" type="boolean" indexed="true" stored="true"/>
|
||||
<dynamicField name="*_f" type="float" indexed="true" stored="true"/>
|
||||
<dynamicField name="*_d" type="double" indexed="true" stored="true"/>
|
||||
<dynamicField name="*_dt" type="date" indexed="true" stored="true"/>
|
||||
<dynamicField name="*_ti" type="tint" indexed="true" stored="true"/>
|
||||
<dynamicField name="*_tl" type="tlong" indexed="true" stored="true"/>
|
||||
<dynamicField name="*_tf" type="tfloat" indexed="true" stored="true"/>
|
||||
<dynamicField name="*_td" type="tdouble" indexed="true" stored="true"/>
|
||||
<dynamicField name="*_tdt" type="tdate" indexed="true" stored="true"/>
|
||||
<dynamicField name="*_pi" type="pint" indexed="true" stored="true"/>
|
||||
<dynamicField name="ignored_*" type="ignored" multiValued="true"/>
|
||||
<dynamicField name="attr_*" type="textgen" indexed="true" stored="true" multiValued="true"/>
|
||||
<dynamicField name="random_*" type="random" />
|
||||
|
||||
</fields>
|
||||
<uniqueKey>item.handle</uniqueKey>
|
||||
<defaultSearchField>item.handle</defaultSearchField>
|
||||
<solrQueryParser defaultOperator="OR"/>
|
||||
</schema>
|
||||
1037
dspace/solr/oai/conf/solrconfig.xml
Normal file
1037
dspace/solr/oai/conf/solrconfig.xml
Normal file
File diff suppressed because it is too large
Load Diff
2
dspace/solr/oai/conf/spellings.txt
Normal file
2
dspace/solr/oai/conf/spellings.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
pizza
|
||||
history
|
||||
57
dspace/solr/oai/conf/stopwords.txt
Normal file
57
dspace/solr/oai/conf/stopwords.txt
Normal file
@@ -0,0 +1,57 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You 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.
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
# a couple of test stopwords to test that the words are really being
|
||||
# configured from this file:
|
||||
stopworda
|
||||
stopwordb
|
||||
|
||||
#Standard english stop words taken from Lucene's StopAnalyzer
|
||||
an
|
||||
and
|
||||
are
|
||||
as
|
||||
at
|
||||
be
|
||||
but
|
||||
by
|
||||
for
|
||||
if
|
||||
in
|
||||
into
|
||||
is
|
||||
it
|
||||
no
|
||||
not
|
||||
of
|
||||
on
|
||||
or
|
||||
s
|
||||
such
|
||||
t
|
||||
that
|
||||
the
|
||||
their
|
||||
then
|
||||
there
|
||||
these
|
||||
they
|
||||
this
|
||||
to
|
||||
was
|
||||
will
|
||||
with
|
||||
|
||||
31
dspace/solr/oai/conf/synonyms.txt
Normal file
31
dspace/solr/oai/conf/synonyms.txt
Normal file
@@ -0,0 +1,31 @@
|
||||
# The ASF licenses this file to You 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.
|
||||
|
||||
#-----------------------------------------------------------------------
|
||||
#some test synonym mappings unlikely to appear in real input text
|
||||
aaa => aaaa
|
||||
bbb => bbbb1 bbbb2
|
||||
ccc => cccc1,cccc2
|
||||
a\=>a => b\=>b
|
||||
a\,a => b\,b
|
||||
fooaaa,baraaa,bazaaa
|
||||
|
||||
# Some synonym groups specific to this example
|
||||
GB,gib,gigabyte,gigabytes
|
||||
MB,mib,megabyte,megabytes
|
||||
Television, Televisions, TV, TVs
|
||||
#notice we use "gib" instead of "GiB" so any WordDelimiterFilter coming
|
||||
#after us won't split it into two words.
|
||||
|
||||
# Synonym mappings can be used for spelling correction too
|
||||
pixima => pixma
|
||||
|
||||
105
dspace/solr/oai/conf/xslt/DRI.xsl
Normal file
105
dspace/solr/oai/conf/xslt/DRI.xsl
Normal file
@@ -0,0 +1,105 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
|
||||
<!--
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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.
|
||||
-->
|
||||
|
||||
<!--
|
||||
Simple transform of Solr query results to HTML
|
||||
-->
|
||||
<xsl:stylesheet version='1.0'
|
||||
xmlns:dri="http://di.tamu.edu/DRI/1.0/"
|
||||
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
|
||||
>
|
||||
|
||||
<xsl:output media-type="text/xml; charset=utf-8" encoding="UTF-8"/>
|
||||
|
||||
<xsl:template match='/'>
|
||||
<dri:div rend="solr-results">
|
||||
<dri:div rend="solr-facets">
|
||||
<xsl:apply-templates select="response/lst[@name='facet_counts']/lst[@name='facet_fields']/lst"/>
|
||||
</dri:div>
|
||||
<dri:div rend="solr-info">
|
||||
<dri:div rend="solr-numFound">
|
||||
<xsl:value-of select="response/result/@numFound"/>
|
||||
</dri:div>
|
||||
<dri:div rend="solr-start">
|
||||
<xsl:value-of select="response/result/@start"/>
|
||||
</dri:div>
|
||||
<dri:div rend="solr-dspace">
|
||||
<xsl:value-of select="response/lst[@name='responseHeader']/lst[@name='params']/str[@name='dspace']"/>
|
||||
</dri:div>
|
||||
<dri:div rend="contextPath">
|
||||
<xsl:value-of select="response/lst[@name='responseHeader']/lst[@name='params']/str[@name='contextPath']"/>
|
||||
</dri:div>
|
||||
<dri:div rend="queryString">
|
||||
<xsl:value-of select="response/lst[@name='responseHeader']/lst[@name='params']/str[@name='queryString']"/>
|
||||
</dri:div>
|
||||
<dri:div rend="URI">
|
||||
<xsl:value-of select="response/lst[@name='responseHeader']/lst[@name='params']/str[@name='URI']"/>
|
||||
</dri:div>
|
||||
</dri:div>
|
||||
<dri:div rend="solr-facet-queries">
|
||||
<dri:list n="facet">
|
||||
<xsl:apply-templates select="response/lst[@name='responseHeader']/lst[@name='params']/str[@name='fq']" mode="facet-field"/>
|
||||
<xsl:apply-templates select="response/lst[@name='responseHeader']/lst[@name='params']/arr[@name='fq']/str" mode="facet-field"/>
|
||||
</dri:list>
|
||||
</dri:div>
|
||||
<dri:div rend="solr-objects">
|
||||
<dri:referenceSet type="summaryList">
|
||||
<xsl:apply-templates select="response/result/doc"/>
|
||||
</dri:referenceSet>
|
||||
</dri:div>
|
||||
</dri:div>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="doc">
|
||||
<dri:reference repositoryID="123456789" type="DSpace Item">
|
||||
<xsl:attribute name="url">
|
||||
<xsl:text>/metadata/handle/</xsl:text>
|
||||
<xsl:value-of select="str[@name = 'handle']"/>
|
||||
<xsl:text>/mets.xml</xsl:text>
|
||||
</xsl:attribute>
|
||||
</dri:reference>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="lst">
|
||||
<dri:list n="facet">
|
||||
<dri:head>
|
||||
<xsl:value-of select="@name"/>
|
||||
</dri:head>
|
||||
<xsl:apply-templates select="*" mode="facet"/>
|
||||
</dri:list>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="*" mode="facet">
|
||||
<dri:item>
|
||||
<dri:xref rend="facet"> <!-- TODO: I don't think rend is allowed per definition -->
|
||||
<xsl:attribute name="target">
|
||||
<xsl:value-of select="."/>
|
||||
</xsl:attribute>
|
||||
<xsl:value-of select="@name"/>
|
||||
</dri:xref>
|
||||
</dri:item>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="str" mode="facet-field">
|
||||
<dri:item>
|
||||
<xsl:value-of select="."/>
|
||||
</dri:item>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
||||
132
dspace/solr/oai/conf/xslt/example.xsl
Normal file
132
dspace/solr/oai/conf/xslt/example.xsl
Normal file
@@ -0,0 +1,132 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
|
||||
<!--
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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.
|
||||
-->
|
||||
|
||||
<!--
|
||||
Simple transform of Solr query results to HTML
|
||||
-->
|
||||
<xsl:stylesheet version='1.0'
|
||||
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
|
||||
>
|
||||
|
||||
<xsl:output media-type="text/html; charset=UTF-8" encoding="UTF-8"/>
|
||||
|
||||
<xsl:variable name="title" select="concat('Solr search results (',response/result/@numFound,' documents)')"/>
|
||||
|
||||
<xsl:template match='/'>
|
||||
<html>
|
||||
<head>
|
||||
<title><xsl:value-of select="$title"/></title>
|
||||
<xsl:call-template name="css"/>
|
||||
</head>
|
||||
<body>
|
||||
<h1><xsl:value-of select="$title"/></h1>
|
||||
<div class="note">
|
||||
This has been formatted by the sample "example.xsl" transform -
|
||||
use your own XSLT to get a nicer page
|
||||
</div>
|
||||
<xsl:apply-templates select="response/result/doc"/>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="doc">
|
||||
<xsl:variable name="pos" select="position()"/>
|
||||
<div class="doc">
|
||||
<table width="100%">
|
||||
<xsl:apply-templates>
|
||||
<xsl:with-param name="pos"><xsl:value-of select="$pos"/></xsl:with-param>
|
||||
</xsl:apply-templates>
|
||||
</table>
|
||||
</div>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="doc/*[@name='score']" priority="100">
|
||||
<xsl:param name="pos"></xsl:param>
|
||||
<tr>
|
||||
<td class="name">
|
||||
<xsl:value-of select="@name"/>
|
||||
</td>
|
||||
<td class="value">
|
||||
<xsl:value-of select="."/>
|
||||
|
||||
<xsl:if test="boolean(//lst[@name='explain'])">
|
||||
<xsl:element name="a">
|
||||
<!-- can't allow whitespace here -->
|
||||
<xsl:attribute name="href">javascript:toggle("<xsl:value-of select="concat('exp-',$pos)" />");</xsl:attribute>?</xsl:element>
|
||||
<br/>
|
||||
<xsl:element name="div">
|
||||
<xsl:attribute name="class">exp</xsl:attribute>
|
||||
<xsl:attribute name="id">
|
||||
<xsl:value-of select="concat('exp-',$pos)" />
|
||||
</xsl:attribute>
|
||||
<xsl:value-of select="//lst[@name='explain']/str[position()=$pos]"/>
|
||||
</xsl:element>
|
||||
</xsl:if>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="doc/arr" priority="100">
|
||||
<tr>
|
||||
<td class="name">
|
||||
<xsl:value-of select="@name"/>
|
||||
</td>
|
||||
<td class="value">
|
||||
<ul>
|
||||
<xsl:for-each select="*">
|
||||
<li><xsl:value-of select="."/></li>
|
||||
</xsl:for-each>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="doc/*">
|
||||
<tr>
|
||||
<td class="name">
|
||||
<xsl:value-of select="@name"/>
|
||||
</td>
|
||||
<td class="value">
|
||||
<xsl:value-of select="."/>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="*"/>
|
||||
|
||||
<xsl:template name="css">
|
||||
<script>
|
||||
function toggle(id) {
|
||||
var obj = document.getElementById(id);
|
||||
obj.style.display = (obj.style.display != 'block') ? 'block' : 'none';
|
||||
}
|
||||
</script>
|
||||
<style type="text/css">
|
||||
body { font-family: "Lucida Grande", sans-serif }
|
||||
td.name { font-style: italic; font-size:80%; }
|
||||
td { vertical-align: top; }
|
||||
ul { margin: 0px; margin-left: 1em; padding: 0px; }
|
||||
.note { font-size:80%; }
|
||||
.doc { margin-top: 1em; border-top: solid grey 1px; }
|
||||
.exp { display: none; font-family: monospace; white-space: pre; }
|
||||
</style>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
||||
67
dspace/solr/oai/conf/xslt/example_atom.xsl
Normal file
67
dspace/solr/oai/conf/xslt/example_atom.xsl
Normal file
@@ -0,0 +1,67 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
|
||||
<!--
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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.
|
||||
-->
|
||||
|
||||
<!--
|
||||
Simple transform of Solr query results to Atom
|
||||
-->
|
||||
|
||||
<xsl:stylesheet version='1.0'
|
||||
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
|
||||
|
||||
<xsl:output
|
||||
method="xml"
|
||||
encoding="utf-8"
|
||||
media-type="text/xml; charset=UTF-8"
|
||||
/>
|
||||
|
||||
<xsl:template match='/'>
|
||||
<xsl:variable name="query" select="response/lst[@name='responseHeader']/lst[@name='params']/str[@name='q']"/>
|
||||
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||
<title>Example Solr Atom 1.0 Feed</title>
|
||||
<subtitle>
|
||||
This has been formatted by the sample "example_atom.xsl" transform -
|
||||
use your own XSLT to get a nicer Atom feed.
|
||||
</subtitle>
|
||||
<author>
|
||||
<name>Apache Solr</name>
|
||||
<email>solr-user@lucene.apache.org</email>
|
||||
</author>
|
||||
<link rel="self" type="application/atom+xml"
|
||||
href="http://localhost:8983/solr/q={$query}&wt=xslt&tr=atom.xsl"/>
|
||||
<updated>
|
||||
<xsl:value-of select="response/result/doc[position()=1]/date[@name='timestamp']"/>
|
||||
</updated>
|
||||
<id>tag:localhost,2007:example</id>
|
||||
<xsl:apply-templates select="response/result/doc"/>
|
||||
</feed>
|
||||
</xsl:template>
|
||||
|
||||
<!-- search results xslt -->
|
||||
<xsl:template match="doc">
|
||||
<xsl:variable name="id" select="str[@name='id']"/>
|
||||
<entry>
|
||||
<title><xsl:value-of select="str[@name='name']"/></title>
|
||||
<link href="http://localhost:8983/solr/select?q={$id}"/>
|
||||
<id>tag:localhost,2007:<xsl:value-of select="$id"/></id>
|
||||
<summary><xsl:value-of select="arr[@name='features']"/></summary>
|
||||
<updated><xsl:value-of select="date[@name='timestamp']"/></updated>
|
||||
</entry>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
||||
66
dspace/solr/oai/conf/xslt/example_rss.xsl
Normal file
66
dspace/solr/oai/conf/xslt/example_rss.xsl
Normal file
@@ -0,0 +1,66 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
|
||||
<!--
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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.
|
||||
-->
|
||||
|
||||
<!--
|
||||
Simple transform of Solr query results to RSS
|
||||
-->
|
||||
|
||||
<xsl:stylesheet version='1.0'
|
||||
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
|
||||
|
||||
<xsl:output
|
||||
method="xml"
|
||||
encoding="utf-8"
|
||||
media-type="text/xml; charset=UTF-8"
|
||||
/>
|
||||
<xsl:template match='/'>
|
||||
<rss version="2.0">
|
||||
<channel>
|
||||
<title>Example Solr RSS 2.0 Feed</title>
|
||||
<link>http://localhost:8983/solr</link>
|
||||
<description>
|
||||
This has been formatted by the sample "example_rss.xsl" transform -
|
||||
use your own XSLT to get a nicer RSS feed.
|
||||
</description>
|
||||
<language>en-us</language>
|
||||
<docs>http://localhost:8983/solr</docs>
|
||||
<xsl:apply-templates select="response/result/doc"/>
|
||||
</channel>
|
||||
</rss>
|
||||
</xsl:template>
|
||||
|
||||
<!-- search results xslt -->
|
||||
<xsl:template match="doc">
|
||||
<xsl:variable name="id" select="str[@name='id']"/>
|
||||
<xsl:variable name="timestamp" select="date[@name='timestamp']"/>
|
||||
<item>
|
||||
<title><xsl:value-of select="str[@name='name']"/></title>
|
||||
<link>
|
||||
http://localhost:8983/solr/select?q=id:<xsl:value-of select="$id"/>
|
||||
</link>
|
||||
<description>
|
||||
<xsl:value-of select="arr[@name='features']"/>
|
||||
</description>
|
||||
<pubDate><xsl:value-of select="$timestamp"/></pubDate>
|
||||
<guid>
|
||||
http://localhost:8983/solr/select?q=id:<xsl:value-of select="$id"/>
|
||||
</guid>
|
||||
</item>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
337
dspace/solr/oai/conf/xslt/luke.xsl
Normal file
337
dspace/solr/oai/conf/xslt/luke.xsl
Normal file
@@ -0,0 +1,337 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You 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.
|
||||
-->
|
||||
|
||||
|
||||
<!--
|
||||
Display the luke request handler with graphs
|
||||
-->
|
||||
<xsl:stylesheet
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
version="1.0"
|
||||
>
|
||||
<xsl:output
|
||||
method="html"
|
||||
encoding="UTF-8"
|
||||
media-type="text/html; charset=UTF-8"
|
||||
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
|
||||
/>
|
||||
|
||||
<xsl:variable name="title">Solr Luke Request Handler Response</xsl:variable>
|
||||
|
||||
<xsl:template match="/">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="solr-admin.css"/>
|
||||
<link rel="icon" href="favicon.ico" type="image/ico"/>
|
||||
<link rel="shortcut icon" href="favicon.ico" type="image/ico"/>
|
||||
<title>
|
||||
<xsl:value-of select="$title"/>
|
||||
</title>
|
||||
<xsl:call-template name="css"/>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<h1>
|
||||
<xsl:value-of select="$title"/>
|
||||
</h1>
|
||||
<div class="doc">
|
||||
<ul>
|
||||
<xsl:if test="response/lst[@name='index']">
|
||||
<li>
|
||||
<a href="#index">Index Statistics</a>
|
||||
</li>
|
||||
</xsl:if>
|
||||
<xsl:if test="response/lst[@name='fields']">
|
||||
<li>
|
||||
<a href="#fields">Field Statistics</a>
|
||||
<ul>
|
||||
<xsl:for-each select="response/lst[@name='fields']/lst">
|
||||
<li>
|
||||
<a href="#{@name}">
|
||||
<xsl:value-of select="@name"/>
|
||||
</a>
|
||||
</li>
|
||||
</xsl:for-each>
|
||||
</ul>
|
||||
</li>
|
||||
</xsl:if>
|
||||
<xsl:if test="response/lst[@name='doc']">
|
||||
<li>
|
||||
<a href="#doc">Document statistics</a>
|
||||
</li>
|
||||
</xsl:if>
|
||||
</ul>
|
||||
</div>
|
||||
<xsl:if test="response/lst[@name='index']">
|
||||
<h2><a name="index"/>Index Statistics</h2>
|
||||
<xsl:apply-templates select="response/lst[@name='index']"/>
|
||||
</xsl:if>
|
||||
<xsl:if test="response/lst[@name='fields']">
|
||||
<h2><a name="fields"/>Field Statistics</h2>
|
||||
<xsl:apply-templates select="response/lst[@name='fields']"/>
|
||||
</xsl:if>
|
||||
<xsl:if test="response/lst[@name='doc']">
|
||||
<h2><a name="doc"/>Document statistics</h2>
|
||||
<xsl:apply-templates select="response/lst[@name='doc']"/>
|
||||
</xsl:if>
|
||||
</body>
|
||||
</html>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="lst">
|
||||
<xsl:if test="parent::lst">
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="doc">
|
||||
<xsl:call-template name="list"/>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:if>
|
||||
<xsl:if test="not(parent::lst)">
|
||||
<div class="doc">
|
||||
<xsl:call-template name="list"/>
|
||||
</div>
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="list">
|
||||
<xsl:if test="count(child::*)>0">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">
|
||||
<p>
|
||||
<a name="{@name}"/>
|
||||
</p>
|
||||
<xsl:value-of select="@name"/>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<xsl:choose>
|
||||
<xsl:when
|
||||
test="@name='histogram'">
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<xsl:call-template name="histogram"/>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:apply-templates/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</tbody>
|
||||
</table>
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="histogram">
|
||||
<div class="doc">
|
||||
<xsl:call-template name="barchart">
|
||||
<xsl:with-param name="max_bar_width">50</xsl:with-param>
|
||||
<xsl:with-param name="iwidth">800</xsl:with-param>
|
||||
<xsl:with-param name="iheight">160</xsl:with-param>
|
||||
<xsl:with-param name="fill">blue</xsl:with-param>
|
||||
</xsl:call-template>
|
||||
</div>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="barchart">
|
||||
<xsl:param name="max_bar_width"/>
|
||||
<xsl:param name="iwidth"/>
|
||||
<xsl:param name="iheight"/>
|
||||
<xsl:param name="fill"/>
|
||||
<xsl:variable name="max">
|
||||
<xsl:for-each select="int">
|
||||
<xsl:sort data-type="number" order="descending"/>
|
||||
<xsl:if test="position()=1">
|
||||
<xsl:value-of select="."/>
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
</xsl:variable>
|
||||
<xsl:variable name="bars">
|
||||
<xsl:value-of select="count(int)"/>
|
||||
</xsl:variable>
|
||||
<xsl:variable name="bar_width">
|
||||
<xsl:choose>
|
||||
<xsl:when test="$max_bar_width < ($iwidth div $bars)">
|
||||
<xsl:value-of select="$max_bar_width"/>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="$iwidth div $bars"/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:variable>
|
||||
<table class="histogram">
|
||||
<tbody>
|
||||
<tr>
|
||||
<xsl:for-each select="int">
|
||||
<td>
|
||||
<xsl:value-of select="."/>
|
||||
<div class="histogram">
|
||||
<xsl:attribute name="style">background-color: <xsl:value-of select="$fill"/>; width: <xsl:value-of select="$bar_width"/>px; height: <xsl:value-of select="($iheight*number(.)) div $max"/>px;</xsl:attribute>
|
||||
</div>
|
||||
</td>
|
||||
</xsl:for-each>
|
||||
</tr>
|
||||
<tr>
|
||||
<xsl:for-each select="int">
|
||||
<td>
|
||||
<xsl:value-of select="@name"/>
|
||||
</td>
|
||||
</xsl:for-each>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="keyvalue">
|
||||
<xsl:choose>
|
||||
<xsl:when test="@name">
|
||||
<tr>
|
||||
<td class="name">
|
||||
<xsl:value-of select="@name"/>
|
||||
</td>
|
||||
<td class="value">
|
||||
<xsl:value-of select="."/>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="."/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="int|bool|long|float|double|uuid|date">
|
||||
<xsl:call-template name="keyvalue"/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="arr">
|
||||
<tr>
|
||||
<td class="name">
|
||||
<xsl:value-of select="@name"/>
|
||||
</td>
|
||||
<td class="value">
|
||||
<ul>
|
||||
<xsl:for-each select="child::*">
|
||||
<li>
|
||||
<xsl:apply-templates/>
|
||||
</li>
|
||||
</xsl:for-each>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="str">
|
||||
<xsl:choose>
|
||||
<xsl:when test="@name='schema' or @name='index' or @name='flags'">
|
||||
<xsl:call-template name="schema"/>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:call-template name="keyvalue"/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="schema">
|
||||
<tr>
|
||||
<td class="name">
|
||||
<xsl:value-of select="@name"/>
|
||||
</td>
|
||||
<td class="value">
|
||||
<xsl:if test="contains(.,'unstored')">
|
||||
<xsl:value-of select="."/>
|
||||
</xsl:if>
|
||||
<xsl:if test="not(contains(.,'unstored'))">
|
||||
<xsl:call-template name="infochar2string">
|
||||
<xsl:with-param name="charList">
|
||||
<xsl:value-of select="."/>
|
||||
</xsl:with-param>
|
||||
</xsl:call-template>
|
||||
</xsl:if>
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="infochar2string">
|
||||
<xsl:param name="i">1</xsl:param>
|
||||
<xsl:param name="charList"/>
|
||||
|
||||
<xsl:variable name="char">
|
||||
<xsl:value-of select="substring($charList,$i,1)"/>
|
||||
</xsl:variable>
|
||||
<xsl:choose>
|
||||
<xsl:when test="$char='I'">
|
||||
<xsl:value-of select="/response/lst[@name='info']/lst/str[@name='I']"/> - </xsl:when>
|
||||
<xsl:when test="$char='T'">
|
||||
<xsl:value-of select="/response/lst[@name='info']/lst/str[@name='T']"/> - </xsl:when>
|
||||
<xsl:when test="$char='S'">
|
||||
<xsl:value-of select="/response/lst[@name='info']/lst/str[@name='S']"/> - </xsl:when>
|
||||
<xsl:when test="$char='M'">
|
||||
<xsl:value-of select="/response/lst[@name='info']/lst/str[@name='M']"/> - </xsl:when>
|
||||
<xsl:when test="$char='V'">
|
||||
<xsl:value-of select="/response/lst[@name='info']/lst/str[@name='V']"/> - </xsl:when>
|
||||
<xsl:when test="$char='o'">
|
||||
<xsl:value-of select="/response/lst[@name='info']/lst/str[@name='o']"/> - </xsl:when>
|
||||
<xsl:when test="$char='p'">
|
||||
<xsl:value-of select="/response/lst[@name='info']/lst/str[@name='p']"/> - </xsl:when>
|
||||
<xsl:when test="$char='O'">
|
||||
<xsl:value-of select="/response/lst[@name='info']/lst/str[@name='O']"/> - </xsl:when>
|
||||
<xsl:when test="$char='L'">
|
||||
<xsl:value-of select="/response/lst[@name='info']/lst/str[@name='L']"/> - </xsl:when>
|
||||
<xsl:when test="$char='B'">
|
||||
<xsl:value-of select="/response/lst[@name='info']/lst/str[@name='B']"/> - </xsl:when>
|
||||
<xsl:when test="$char='C'">
|
||||
<xsl:value-of select="/response/lst[@name='info']/lst/str[@name='C']"/> - </xsl:when>
|
||||
<xsl:when test="$char='f'">
|
||||
<xsl:value-of select="/response/lst[@name='info']/lst/str[@name='f']"/> - </xsl:when>
|
||||
<xsl:when test="$char='l'">
|
||||
<xsl:value-of select="/response/lst[@name='info']/lst/str[@name='l']"/> -
|
||||
</xsl:when>
|
||||
</xsl:choose>
|
||||
|
||||
<xsl:if test="not($i>=string-length($charList))">
|
||||
<xsl:call-template name="infochar2string">
|
||||
<xsl:with-param name="i">
|
||||
<xsl:value-of select="$i+1"/>
|
||||
</xsl:with-param>
|
||||
<xsl:with-param name="charList">
|
||||
<xsl:value-of select="$charList"/>
|
||||
</xsl:with-param>
|
||||
</xsl:call-template>
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
<xsl:template name="css">
|
||||
<style type="text/css">
|
||||
<![CDATA[
|
||||
td.name {font-style: italic; font-size:80%; }
|
||||
.doc { margin: 0.5em; border: solid grey 1px; }
|
||||
.exp { display: none; font-family: monospace; white-space: pre; }
|
||||
div.histogram { background: none repeat scroll 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;}
|
||||
table.histogram { width: auto; vertical-align: bottom; }
|
||||
table.histogram td, table.histogram th { text-align: center; vertical-align: bottom; border-bottom: 1px solid #ff9933; width: auto; }
|
||||
]]>
|
||||
</style>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
@@ -1,36 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You 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.
|
||||
-->
|
||||
|
||||
<!--
|
||||
All (relative) paths are relative to the installation path
|
||||
|
||||
persistent: Save changes made via the API to this file
|
||||
sharedLib: path to a lib directory that will be shared across all cores
|
||||
-->
|
||||
<solr persistent="false">
|
||||
|
||||
<!--
|
||||
adminPath: RequestHandler path to manage cores.
|
||||
If 'null' (or absent), cores will not be manageable via REST
|
||||
-->
|
||||
<cores adminPath="/admin/cores">
|
||||
<core name="search" instanceDir="search" />
|
||||
<core name="statistics" instanceDir="statistics" />
|
||||
</cores>
|
||||
|
||||
</solr>
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You 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.
|
||||
-->
|
||||
|
||||
<!--
|
||||
All (relative) paths are relative to the installation path
|
||||
|
||||
persistent: Save changes made via the API to this file
|
||||
sharedLib: path to a lib directory that will be shared across all cores
|
||||
-->
|
||||
<solr persistent="false">
|
||||
|
||||
<!--
|
||||
adminPath: RequestHandler path to manage cores.
|
||||
If 'null' (or absent), cores will not be manageable via REST
|
||||
-->
|
||||
<cores adminPath="/admin/cores">
|
||||
<core name="search" instanceDir="search" />
|
||||
<core name="statistics" instanceDir="statistics" />
|
||||
<core name="oai" instanceDir="oai" />
|
||||
</cores>
|
||||
|
||||
</solr>
|
||||
|
||||
@@ -730,6 +730,10 @@ Common usage:
|
||||
|
||||
<mkdir dir="${dspace.dir}/solr" />
|
||||
|
||||
<!-- Runtime files (Could be erased - just for performing purposes) -->
|
||||
<mkdir dir="${dspace.dir}/var" />
|
||||
<!-- Runtime files for OAI 2.0 -->
|
||||
<mkdir dir="${dspace.dir}/var/oai" />
|
||||
</target>
|
||||
|
||||
|
||||
|
||||
8
pom.xml
8
pom.xml
@@ -236,7 +236,7 @@
|
||||
</profile>
|
||||
|
||||
<!--
|
||||
Builds OAI Gateway WAR for DSpace
|
||||
Builds XOAI Gateway WAR for DSpace
|
||||
-->
|
||||
<profile>
|
||||
<id>dspace-oai</id>
|
||||
@@ -641,11 +641,6 @@
|
||||
<artifactId>mets</artifactId>
|
||||
<version>1.5.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dspace</groupId>
|
||||
<artifactId>oaicat</artifactId>
|
||||
<version>1.5.48</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dspace.dependencies</groupId>
|
||||
<artifactId>dspace-tm-extractors</artifactId>
|
||||
@@ -1197,5 +1192,4 @@
|
||||
<distributionManagement>
|
||||
<!-- further distribution management is found upstream in the sonatype parent -->
|
||||
</distributionManagement>
|
||||
|
||||
</project>
|
||||
|
||||
Reference in New Issue
Block a user