001: /*
002: * RepositoryAdapter.java
003: *
004: * Version: $Revision: 1.3 $
005: *
006: * Date: $Date: 2006/04/26 18:26:46 $
007: *
008: * Copyright (c) 2002-2005, Hewlett-Packard Company and Massachusetts
009: * Institute of Technology. All rights reserved.
010: *
011: * Redistribution and use in source and binary forms, with or without
012: * modification, are permitted provided that the following conditions are
013: * met:
014: *
015: * - Redistributions of source code must retain the above copyright
016: * notice, this list of conditions and the following disclaimer.
017: *
018: * - Redistributions in binary form must reproduce the above copyright
019: * notice, this list of conditions and the following disclaimer in the
020: * documentation and/or other materials provided with the distribution.
021: *
022: * - Neither the name of the Hewlett-Packard Company nor the name of the
023: * Massachusetts Institute of Technology nor the names of their
024: * contributors may be used to endorse or promote products derived from
025: * this software without specific prior written permission.
026: *
027: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
028: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
029: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
030: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
031: * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
032: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
033: * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
034: * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
035: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
036: * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
037: * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
038: * DAMAGE.
039: */
040: package org.dspace.app.xmlui.objectmanager;
041:
042: import java.sql.SQLException;
043:
044: import org.dspace.app.xmlui.wing.AttributeMap;
045: import org.dspace.app.xmlui.wing.Namespace;
046: import org.dspace.app.xmlui.wing.WingException;
047: import org.dspace.content.Collection;
048: import org.dspace.content.Community;
049: import org.dspace.content.DSpaceObject;
050: import org.dspace.core.ConfigurationManager;
051: import org.dspace.core.Constants;
052: import org.dspace.core.Context;
053: import org.xml.sax.SAXException;
054:
055: /**
056: * This is an an adapter which translates a DSpace repository into a METS
057: * document. Unfortunitaly there is no real definition of what this is. So
058: * we just kind of made it up based upon what we saw for the item profile.
059: *
060: * The basic structure is simply two parts, the descriptive metadata and a
061: * structural map. The descriptive metadata is a place to put metadata about
062: * the whole repository. The structural map is used to map relationships
063: * between communities & collections in dspace.
064: *
065: * @author Scott Phillips
066: */
067: public class RepositoryAdapter extends AbstractAdapter {
068:
069: /** MODS namespace */
070: public static String MODS_URI = "http://www.loc.gov/mods/v3";
071: public static Namespace MODS = new Namespace(MODS_URI);
072:
073: /** A space seperated list of descriptive metadata sections */
074: private String dmdSecIDS;
075:
076: /** Dspace context to be able to look up additional objects */
077: private Context context;
078:
079: /**
080: * Construct a new RepositoryAdapter
081: *
082: * @param context
083: * The DSpace context to look up communities / collections.
084: *
085: * @param contextPath
086: * The contextPath of this webapplication.
087: */
088: public RepositoryAdapter(Context context, String contextPath) {
089: super (contextPath);
090: this .context = context;
091: }
092:
093: /**
094: *
095: *
096: *
097: * Abstract methods
098: *
099: *
100: *
101: */
102:
103: /**
104: * Return the handle prefix as the identifier.
105: */
106: protected String getMETSID() {
107: return ConfigurationManager.getProperty("handle.prefix");
108: }
109:
110: /**
111: * The OBJID is used to encode the URL to the object, in this
112: * case the repository which is just at the contextPath.
113: */
114: protected String getMETSOBJID() throws WingException {
115:
116: if (contextPath == null)
117: return "/";
118: else
119: return contextPath + "/";
120: }
121:
122: /**
123: * @return Return the URL for editing this item
124: */
125: protected String getMETSOBJEDIT() {
126: return null;
127: }
128:
129: /**
130: * Return the profile this METS document conforms too...
131: *
132: * FIXME: It dosn't conform to a profile. This needs to be fixed.
133: */
134: protected String getMETSProfile() {
135: return "DRI DSPACE Repository Profile 1.0";
136: }
137:
138: /**
139: * Return a friendly label for the METS document stating that this is a
140: * DSpace repository.
141: */
142: protected String getMETSLabel() {
143: return "DSpace Repository";
144: }
145:
146: /**
147: *
148: *
149: *
150: * METS structural methods
151: *
152: *
153: *
154: */
155:
156: /**
157: * Render the repository's descriptive metadata section.
158: *
159: * For a the DSPace repository we just grab a few items
160: * from the config file and put them into the descriptive
161: * section, such as the name, hostname, handle prefix, and
162: * default language.
163: *
164: */
165: protected void renderDescriptiveSection() throws SAXException {
166: AttributeMap attributes;
167:
168: // Generate our ids
169: String dmdID = getGenericID("dmd_");
170: String groupID = getGenericID("group_dmd_");
171:
172: // ////////////////////////////////
173: // Start a single dmdSec
174: attributes = new AttributeMap();
175: attributes.put("ID", dmdID);
176: attributes.put("GROUPID", groupID);
177: startElement(METS, "dmdSec", attributes);
178:
179: // ////////////////////////////////
180: // Start a metadata wrapper (hardcoded to mods)
181: attributes = new AttributeMap();
182: attributes.put("MDTYPE", "OTHER");
183: attributes.put("OTHERMDTYPE", "DIM");
184: startElement(METS, "mdWrap", attributes);
185:
186: // ////////////////////////////////
187: // Start the xml data
188: startElement(METS, "xmlData");
189:
190: /////////////////////////////////
191: // Start the DIM element
192: attributes = new AttributeMap();
193: attributes
194: .put("dspaceType", Constants.typeText[Constants.SITE]);
195: startElement(DIM, "dim", attributes);
196:
197: // Entry for dspace.name
198: attributes = new AttributeMap();
199: attributes.put("mdschema", "dspace");
200: attributes.put("element", "name");
201: startElement(DIM, "field", attributes);
202: sendCharacters(ConfigurationManager.getProperty("dspace.name"));
203: endElement(DIM, "field");
204:
205: // Entry for dspace.hostname
206: attributes = new AttributeMap();
207: attributes.put("mdschema", "dspace");
208: attributes.put("element", "hostname");
209: startElement(DIM, "field", attributes);
210: sendCharacters(ConfigurationManager
211: .getProperty("dspace.hostname"));
212: endElement(DIM, "field");
213:
214: // Entry for handle.prefix
215: attributes = new AttributeMap();
216: attributes.put("mdschema", "dspace");
217: attributes.put("element", "handle");
218: startElement(DIM, "field", attributes);
219: sendCharacters(ConfigurationManager
220: .getProperty("handle.prefix"));
221: endElement(DIM, "field");
222:
223: // Entry for default.language
224: attributes = new AttributeMap();
225: attributes.put("mdschema", "dspace");
226: attributes.put("element", "default");
227: attributes.put("qualifier", "language");
228: startElement(DIM, "field", attributes);
229: sendCharacters(ConfigurationManager
230: .getProperty("default.language"));
231: endElement(DIM, "field");
232:
233: // ///////////////////////////////
234: // End the DIM element
235: endElement(DIM, "dim");
236:
237: // End all the open elements.
238: endElement(METS, "xmlData");
239: endElement(METS, "mdWrap");
240: endElement(METS, "dmdSec");
241:
242: // Remember the IDS
243: this .dmdSecIDS = dmdID;
244: }
245:
246: /**
247: * Render the repository's structure map. This map will include a refrence to
248: * all the community and collection objects showing how they are related to
249: * one another.
250: */
251: protected void renderStructureMap() throws SQLException,
252: SAXException {
253: AttributeMap attributes;
254:
255: // //////////////////////////
256: // Start the new struct map
257: attributes = new AttributeMap();
258: attributes.put("TYPE", "LOGICAL");
259: attributes.put("LABEL", "DSpace");
260: startElement(METS, "structMap", attributes);
261:
262: // ////////////////////////////////
263: // Start the special first division
264: attributes = new AttributeMap();
265: attributes.put("TYPE", "DSpace Repository");
266: // add references to the Descriptive metadata
267: if (dmdSecIDS != null)
268: attributes.put("DMDID", dmdSecIDS);
269: startElement(METS, "div", attributes);
270:
271: // Put each root level node into the document.
272: for (Community community : Community.findAllTop(context)) {
273: renderStructuralDiv(community);
274: }
275:
276: // //////////////////
277: // Close special first division and structural map
278: endElement(METS, "div");
279: endElement(METS, "structMap");
280:
281: }
282:
283: /**
284: *
285: *
286: *
287: * private helpfull methods
288: *
289: *
290: *
291: */
292:
293: /**
294: * Recursively the DSpace hirearchy rendering each container and subcontainers.
295: *
296: * @param dso
297: * The DSpace Object to be rendered.
298: */
299: private void renderStructuralDiv(DSpaceObject dso)
300: throws SAXException, SQLException {
301: AttributeMap attributes;
302:
303: // ////////////////////////////////
304: // Start the new div for this repository container
305: attributes = new AttributeMap();
306: if (dso instanceof Community)
307: attributes.put("TYPE", "DSpace Community");
308: else if (dso instanceof Collection)
309: attributes.put("TYPE", "DSpace Collection");
310: startElement(METS, "div", attributes);
311:
312: // //////////////////////////////////
313: // Start a metadata pointer for this container
314: attributes = new AttributeMap();
315: AttributeMap attributesXLINK = new AttributeMap();
316: attributesXLINK.setNamespace(XLINK);
317:
318: attributes.put("LOCTYPE", "URL");
319: attributesXLINK.put("href", "/metadata/handle/"
320: + dso.getHandle() + "/mets.xml");
321: startElement(METS, "mptr", attributes, attributesXLINK);
322: endElement(METS, "mptr");
323:
324: // Recurse to insure that our children are also included even if this
325: // node allready existed in the div structure.
326: if (dso instanceof Community) {
327: for (DSpaceObject child : ((Community) dso)
328: .getCollections())
329: renderStructuralDiv(child);
330:
331: for (DSpaceObject child : ((Community) dso)
332: .getSubcommunities())
333: renderStructuralDiv(child);
334: }
335:
336: // ////////////////////
337: // Close division
338: endElement(METS, "div");
339: }
340: }
|