KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > dspace > content > packager > DSpaceMETSDisseminator


1 /*
2  * DSpaceMETSDisseminator.java
3  *
4  * Version: $Revision: 1.1 $
5  *
6  * Date: $Date: 2006/03/17 00:04:38 $
7  *
8  * Copyright (c) 2002-2005, Hewlett-Packard Company and Massachusetts
9  * Institute of Technology. All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions are
13  * met:
14  *
15  * - Redistributions of source code must retain the above copyright
16  * notice, this list of conditions and the following disclaimer.
17  *
18  * - Redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution.
21  *
22  * - Neither the name of the Hewlett-Packard Company nor the name of the
23  * Massachusetts Institute of Technology nor the names of their
24  * contributors may be used to endorse or promote products derived from
25  * this software without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
33  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
34  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
35  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
36  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
37  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
38  * DAMAGE.
39  */

40
41 package org.dspace.content.packager;
42
43 import java.io.IOException JavaDoc;
44 import java.io.InputStream JavaDoc;
45 import java.sql.SQLException JavaDoc;
46
47 import org.apache.log4j.Logger;
48 import org.dspace.authorize.AuthorizeException;
49 import org.dspace.content.Bitstream;
50 import org.dspace.content.BitstreamFormat;
51 import org.dspace.content.Bundle;
52 import org.dspace.content.Item;
53 import org.dspace.core.Constants;
54 import org.dspace.core.Context;
55 import org.dspace.license.CreativeCommons;
56
57 import edu.harvard.hul.ois.mets.AmdSec;
58 import edu.harvard.hul.ois.mets.BinData;
59 import edu.harvard.hul.ois.mets.Loctype;
60 import edu.harvard.hul.ois.mets.MdRef;
61 import edu.harvard.hul.ois.mets.MdWrap;
62 import edu.harvard.hul.ois.mets.Mdtype;
63 import edu.harvard.hul.ois.mets.Mets;
64 import edu.harvard.hul.ois.mets.RightsMD;
65 import edu.harvard.hul.ois.mets.helper.Base64;
66 import edu.harvard.hul.ois.mets.helper.MetsException;
67
68 /**
69  * Packager plugin to produce a
70  * METS (Metadata Encoding & Transmission Standard) package
71  * that is accepted as a DSpace METS SIP (Submission Information Package).
72  * See <a HREF="http://www.loc.gov/standards/mets/">http://www.loc.gov/standards/mets/</a>
73  * for more information on METS.
74  * <p>
75  * This class does not produce a true DSpace DIP, because there was no
76  * DIP standard when it was implemented. It does contain some features
77  * beyond the requirements of a SIP (e.g. deposit licenses), anticipating
78  * the DIP specification.
79  * <p>
80  * DSpaceMETSDisseminator was intended to be an useful example of a packager
81  * plugin, and a way to create packages acceptable to the METS SIP importer.
82  *
83  * @author Larry Stone
84  * @version $Revision: 1.1 $
85  */

86 public class DSpaceMETSDisseminator
87     extends AbstractMETSDisseminator
88 {
89     /** log4j category */
90     private static Logger log = Logger.getLogger(DSpaceMETSDisseminator.class);
91
92     /**
93      * Identifier for the package we produce, i.e. DSpace METS SIP
94      * Profile. Though not strictly true, there is no DIP standard yet
95      * so it's the most meaningful label we can apply.
96      */

97     private final static String JavaDoc PROFILE_LABEL = "DSpace METS SIP Profile 1.0";
98
99     // MDTYPE value for deposit license -- "magic string"
100
private final static String JavaDoc DSPACE_DEPOSIT_LICENSE_MDTYPE =
101                                 "DSpace Deposit License";
102
103     // MDTYPE value for CC license -- "magic string"
104
private final static String JavaDoc CREATIVE_COMMONS_LICENSE_MDTYPE =
105                                 "Creative Commons";
106
107     /**
108      * Return identifier string for the profile this produces.
109      *
110      * @return string name of profile.
111      */

112     public String JavaDoc getProfile()
113     {
114         return PROFILE_LABEL;
115     }
116
117     /**
118      * Returns name of METS fileGrp corresponding to a DSpace bundle name.
119      * They are mostly the same except for bundle "ORIGINAL" maps to "CONTENT".
120      * Don't worry about the metadata bundles since they are not
121      * packaged as fileGrps, but in *mdSecs.
122      * @param bname name of DSpace bundle.
123      * @return string name of fileGrp
124      */

125     public String JavaDoc bundleToFileGrp(String JavaDoc bname)
126     {
127         if (bname.equals("ORIGINAL"))
128             return "CONTENT";
129         else
130             return bname;
131     }
132
133     /**
134      * Get DMD choice for Item. It defaults to MODS, but is overridden
135      * by the package parameters if they contain any "dmd" keys. The
136      * params may contain one or more values for "dmd"; each of those is
137      * the name of a crosswalk plugin, optionally followed by colon and
138      * its METS MDTYPE name.
139      */

140     public String JavaDoc [] getDmdTypes(PackageParameters params)
141         throws SQLException JavaDoc, IOException JavaDoc, AuthorizeException
142     {
143
144     // XXX maybe let dmd choices be configured in DSpace config too?
145

146         String JavaDoc result[] = null;
147         if (params != null)
148             result = params.getProperties("dmd");
149         if (result == null || result.length == 0)
150         {
151             result = new String JavaDoc[1];
152             result[0] = "MODS";
153         }
154         return result;
155     }
156
157     /**
158      * Get name of technical metadata crosswalk for Bitstreams.
159      * Default is PREMIS. This is both the name of the crosswalk plugin
160      * and the METS MDTYPE.
161      */

162     public String JavaDoc getTechMdType(PackageParameters params)
163         throws SQLException JavaDoc, IOException JavaDoc, AuthorizeException
164     {
165         return "PREMIS";
166     }
167
168     /**
169      * Add rights MD (licenses) for DSpace item. These
170      * may include a deposit license, and Creative Commons.
171      */

172     public void addRightsMd(Context context, Item item, AmdSec amdSec)
173         throws SQLException JavaDoc, IOException JavaDoc, AuthorizeException, MetsException
174     {
175         addDepositLicense(context, item, amdSec);
176         addCreativeCommons(context, item, amdSec);
177     }
178
179     // Add deposit license, if any, as external file.
180
// Give it a unique name including the SID in case there are other
181
// deposit license artifacts in the Item.
182
private boolean addDepositLicense(Context context, Item item, AmdSec amdSec)
183         throws SQLException JavaDoc, IOException JavaDoc, AuthorizeException, MetsException
184     {
185         Bitstream licenseBs = findDepositLicense(context, item);
186
187         if (licenseBs == null)
188             return false;
189         else
190         {
191             String JavaDoc resource = "depositlicense_"+
192                               String.valueOf(licenseBs.getSequenceID())+".txt";
193             addRightsStream(licenseBs.retrieve(), resource, "text/plain",
194                            DSPACE_DEPOSIT_LICENSE_MDTYPE, amdSec);
195             return true;
196         }
197     }
198
199     // if there's a CC RDF license, chuck it in external file.
200
private boolean addCreativeCommons(Context context, Item item, AmdSec amdSec)
201         throws SQLException JavaDoc, IOException JavaDoc, AuthorizeException, MetsException
202     {
203         // License as <rightsMD><mdWrap><binData>base64encoded</binData>...
204
Bitstream cc;
205         
206         if ((cc = CreativeCommons.getLicenseRdfBitstream(item)) != null)
207         {
208             addRightsStream(cc.retrieve(),
209                             (gensym("creativecommons") + ".rdf"),
210                             "text/rdf",
211                             CREATIVE_COMMONS_LICENSE_MDTYPE, amdSec);
212         }
213         else if ((cc = CreativeCommons.getLicenseTextBitstream(item)) != null)
214         {
215             addRightsStream(cc.retrieve(),
216                             (gensym("creativecommons") + ".txt"),
217                             "text/plain",
218                             CREATIVE_COMMONS_LICENSE_MDTYPE, amdSec);
219         }
220         else
221             return false;
222         return true;
223     }
224
225     // utility to add a stream to the METS manifest.
226
// use external file and mdRef if possible, wrap and binData if not.
227
private void addRightsStream(InputStream JavaDoc is , String JavaDoc resourceName,
228                                  String JavaDoc mimeType, String JavaDoc mdType, AmdSec amdSec)
229         throws IOException JavaDoc, MetsException
230     {
231         RightsMD rightsMD = new RightsMD();
232         rightsMD.setID(gensym("rights"));
233         if (extraFiles == null)
234         {
235             MdWrap rightsMDWrap = new MdWrap();
236             rightsMDWrap.setMIMETYPE(mimeType);
237             rightsMDWrap.setMDTYPE(Mdtype.OTHER);
238             rightsMDWrap.setOTHERMDTYPE(mdType);
239             BinData bin = new BinData();
240             bin.getContent().add(new Base64(is));
241             rightsMDWrap.getContent().add(bin);
242             rightsMD.getContent().add(rightsMDWrap);
243         }
244         else
245         {
246             extraFiles.put(resourceName, is);
247             MdRef rightsMDRef = new MdRef();
248             rightsMDRef.setMIMETYPE(mimeType);
249             rightsMDRef.setMDTYPE(Mdtype.OTHER);
250             rightsMDRef.setOTHERMDTYPE(mdType);
251             rightsMDRef.setLOCTYPE(Loctype.URL);
252             rightsMDRef.setXlinkHref(resourceName);
253             rightsMD.getContent().add(rightsMDRef);
254         }
255         amdSec.getContent().add(rightsMD);
256     }
257
258     /**
259      * Utility to find the license bitstream from an item
260      *
261      * @param context
262      * DSpace context
263      * @param item
264      * the item
265      * @return the license bitstream or null
266      *
267      * @throws IOException
268      * if the license bitstream can't be read
269      */

270     private static Bitstream findDepositLicense(Context context, Item item)
271             throws SQLException JavaDoc, IOException JavaDoc, AuthorizeException
272     {
273         // get license format ID
274
int licenseFormatId = -1;
275         BitstreamFormat bf = BitstreamFormat.findByShortDescription(context,
276                 "License");
277         if (bf != null)
278             licenseFormatId = bf.getID();
279
280         Bundle[] bundles = item.getBundles(Constants.LICENSE_BUNDLE_NAME);
281         for (int i = 0; i < bundles.length; i++)
282         {
283             // Assume license will be in its own bundle
284
Bitstream[] bitstreams = bundles[i].getBitstreams();
285
286             if (bitstreams[0].getFormat().getID() == licenseFormatId)
287             {
288                 return bitstreams[0];
289             }
290         }
291
292         // Oops! No license!
293
return null;
294     }
295
296     // This is where we'd elaborate on the default structMap; nothing to add, yet.
297
public void addStructMap(Context context, Item item,
298                                PackageParameters params, Mets mets)
299         throws SQLException JavaDoc, IOException JavaDoc, AuthorizeException, MetsException
300     {
301     }
302 }
303
Popular Tags