001: /*
002: * Copyright (c) 2004-2005, Hewlett-Packard Company and Massachusetts
003: * Institute of Technology. All rights reserved.
004: *
005: * Redistribution and use in source and binary forms, with or without
006: * modification, are permitted provided that the following conditions are
007: * met:
008: *
009: * - Redistributions of source code must retain the above copyright
010: * notice, this list of conditions and the following disclaimer.
011: *
012: * - Redistributions in binary form must reproduce the above copyright
013: * notice, this list of conditions and the following disclaimer in the
014: * documentation and/or other materials provided with the distribution.
015: *
016: * - Neither the name of the Hewlett-Packard Company nor the name of the
017: * Massachusetts Institute of Technology nor the names of their
018: * contributors may be used to endorse or promote products derived from
019: * this software without specific prior written permission.
020: *
021: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
022: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
023: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
024: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
025: * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
026: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
027: * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
028: * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
029: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
030: * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
031: * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
032: * DAMAGE.
033: */
034:
035: package org.dspace.app.oai;
036:
037: import java.io.BufferedInputStream;
038: import java.sql.SQLException;
039: import java.util.Date;
040: import java.util.Properties;
041:
042: import org.apache.commons.codec.binary.Base64;
043: import org.dspace.app.didl.UUIDFactory;
044: import org.dspace.content.Bitstream;
045: import org.dspace.content.Bundle;
046: import org.dspace.content.DCDate;
047: import org.dspace.content.DCValue;
048: import org.dspace.content.Item;
049: import org.dspace.core.ConfigurationManager;
050: import org.dspace.core.Context;
051: import org.dspace.search.HarvestedItemInfo;
052: import org.dspace.storage.bitstore.BitstreamStorageManager;
053:
054: import ORG.oclc.oai.server.crosswalk.Crosswalk;
055: import ORG.oclc.oai.server.verb.CannotDisseminateFormatException;
056: import ORG.oclc.oai.server.verb.ServerVerb;
057:
058: /**
059: * DSpace Item DIDL crosswalk.
060: *
061: * Development of this code was part of the aDORe repository project
062: * by the Research Library of the Los Alamos National Laboratory.
063: *
064: * @author Henry Jerez
065: * @author Los Alamos National Laboratory
066: */
067:
068: public class DIDLCrosswalk extends Crosswalk {
069: public DIDLCrosswalk(Properties properties) {
070: super (
071: "urn:mpeg:mpeg21:2002:02-DIDL-NS http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-21_schema_files/did/didl.xsd ");
072: }
073:
074: public boolean isAvailableFor(Object nativeItem) {
075: // We have DC for everything
076: return true;
077: }
078:
079: public String createMetadata(Object nativeItem)
080: throws CannotDisseminateFormatException {
081: Item item = ((HarvestedItemInfo) nativeItem).item;
082:
083: Date d = ((HarvestedItemInfo) nativeItem).datestamp;
084: String ITEMDATE = new DCDate(d).toString();
085:
086: // Get all the DC
087: DCValue[] allDC = item.getDC(Item.ANY, Item.ANY, Item.ANY);
088:
089: StringBuffer metadata = new StringBuffer();
090: StringBuffer metadata1 = new StringBuffer();
091: String itemhandle = item.getHandle();
092: int maxsize = Integer.parseInt(ConfigurationManager
093: .getProperty("oai.didl.maxresponse"));
094: String currdate = ServerVerb.createResponseDate(new Date());
095:
096: metadata
097: .append("<didl:DIDL ")
098: .append(
099: " xmlns:didl=\"urn:mpeg:mpeg21:2002:02-DIDL-NS\" ")
100: .append(
101: " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ")
102: .append(
103: "xsi:schemaLocation=\"urn:mpeg:mpeg21:2002:02-DIDL-NS http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-21_schema_files/did/didl.xsd \">")
104: .append("<didl:DIDLInfo>")
105: .append(
106: "<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/ \">")
107: .append(currdate).append(
108: "</dcterms:created> </didl:DIDLInfo>").append(
109: "<didl:Item id=\"").append(
110: "uuid-" + UUIDFactory.generateUUID().toString()
111: + "\">");
112: metadata
113: .append("<didl:Descriptor>")
114: .append(
115: "<didl:Statement mimeType=\"application/xml; charset=utf-8\">")
116: .append(
117: "<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\">")
118: .append("urn:hdl:" + itemhandle).append(
119: "</dii:Identifier>")
120: .append("</didl:Statement>").append(
121: "</didl:Descriptor>");
122: metadata
123: .append("<didl:Descriptor>")
124: .append(
125: "<didl:Statement mimeType=\"application/xml; charset=utf-8\">");
126:
127: for (int i = 0; i < allDC.length; i++) {
128: // Do not include description.provenance
129: boolean description = allDC[i].element
130: .equals("description");
131: boolean provenance = allDC[i].qualifier != null
132: && allDC[i].qualifier.equals("provenance");
133:
134: if (!(description && provenance)) {
135: // Escape XML chars <, > and &
136: String value = allDC[i].value;
137:
138: // First do &'s - need to be careful not to replace the
139: // & in "&" again!
140: int c = -1;
141: while ((c = value.indexOf("&", c + 1)) > -1) {
142: value = value.substring(0, c) + "&"
143: + value.substring(c + 1);
144: }
145:
146: while ((c = value.indexOf("<")) > -1) {
147: value = value.substring(0, c) + "<"
148: + value.substring(c + 1);
149: }
150:
151: while ((c = value.indexOf(">")) > -1) {
152: value = value.substring(0, c) + ">"
153: + value.substring(c + 1);
154: }
155:
156: metadata1.append("<dc:").append(allDC[i].element)
157: .append(">").append(value).append("</dc:")
158: .append(allDC[i].element).append(">");
159: }
160: }
161:
162: metadata
163: .append("<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\">");
164:
165: metadata.append(metadata1);
166:
167: metadata.append("</oai_dc:dc>").append("</didl:Statement>")
168: .append("</didl:Descriptor>");
169:
170: /**putfirst item here**/
171:
172: //**CYCLE HERE!!!!**//
173: try {
174: Bundle[] bundles = item.getBundles("ORIGINAL");
175:
176: if (bundles.length == 0) {
177: metadata
178: .append("<P>There are no files associated with this item.</P>");
179: } else {
180: /**cycle bundles**/
181: for (int i = 0; i < bundles.length; i++) {
182: int flag = 0;
183: Bitstream[] bitstreams = bundles[i].getBitstreams();
184:
185: /**cycle bitstreams**/
186: for (int k = 0; k < bitstreams.length; k++) {
187: // Skip internal types
188: if (!bitstreams[k].getFormat().isInternal()) {
189: if (flag == 0) {
190: flag = 1;
191: }
192:
193: metadata.append("<didl:Component id="
194: + "\"uuid-"
195: + UUIDFactory.generateUUID()
196: .toString() + "\">");
197:
198: if (bitstreams[k].getSize() > maxsize) {
199: metadata
200: .append("<didl:Resource ref=\""
201: + ConfigurationManager
202: .getProperty("dspace.url")
203: + "/bitstream/"
204: + itemhandle
205: + "/"
206: + bitstreams[k]
207: .getSequenceID()
208: + "/"
209: + bitstreams[k]
210: .getName());
211: metadata.append("\" mimeType=\"");
212: metadata.append(bitstreams[k]
213: .getFormat().getMIMEType());
214: metadata.append("\">");
215: metadata.append("</didl:Resource>");
216: } else {
217:
218: try {
219: metadata
220: .append("<didl:Resource mimeType=\"");
221: metadata.append(bitstreams[k]
222: .getFormat().getMIMEType());
223: metadata
224: .append("\" encoding=\"base64\">");
225:
226: /*
227: * Assume that size of in-line bitstreams will always be
228: * smaller than MAXINT bytes
229: */
230: int intSize = (int) bitstreams[k]
231: .getSize();
232:
233: byte[] buffer = new byte[intSize];
234:
235: Context contextl = new Context();
236: BufferedInputStream bis = new BufferedInputStream(
237: BitstreamStorageManager
238: .retrieve(
239: contextl,
240: bitstreams[k]
241: .getID()));
242: int size = bis.read(buffer);
243: contextl.complete();
244:
245: String encoding = new String(Base64
246: .encodeBase64(buffer),
247: "ASCII");
248: metadata.append(encoding);
249: } catch (Exception ex) {
250: ex.printStackTrace();
251:
252: metadata
253: .append("<didl:Resource ref=\""
254: + ConfigurationManager
255: .getProperty("dspace.url")
256: + "/bitstream/"
257: + itemhandle
258: + "/"
259: + bitstreams[k]
260: .getSequenceID()
261: + "/"
262: + bitstreams[k]
263: .getName());
264: metadata.append("\" mimeType=\"");
265: metadata.append(bitstreams[k]
266: .getFormat().getMIMEType());
267: metadata.append("\">");
268: }
269:
270: metadata.append("</didl:Resource>");
271: }
272: metadata.append("</didl:Component>");
273: }
274: /*end bitstream cycle*/
275: }
276: /*end bundle cycle*/
277: }
278: }
279: } catch (SQLException sqle) {
280: System.err.println("Caught exception:" + sqle.getCause());
281: sqle.printStackTrace();
282: }
283:
284: //**END CYCLE HERE **//
285:
286: metadata.append("</didl:Item>").append("</didl:DIDL>");
287:
288: return metadata.toString();
289: }
290: }
|