/* * HandleUtil.java * * Version: $Revision: 3705 $ * * Date: $Date: 2009-04-11 17:02:24 +0000 (Sat, 11 Apr 2009) $ * * Copyright (c) 2002, Hewlett-Packard Company and Massachusetts * Institute of Technology. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of the Hewlett-Packard Company nor the name of the * Massachusetts Institute of Technology nor the names of their * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. */ package org.dspace.app.xmlui.utils; import java.sql.SQLException; import java.util.Map; import java.util.Stack; import org.apache.cocoon.environment.ObjectModelHelper; import org.apache.cocoon.environment.Request; import org.dspace.app.xmlui.wing.Message; import org.dspace.app.xmlui.wing.WingException; import org.dspace.app.xmlui.wing.element.PageMeta; import org.dspace.content.Bitstream; import org.dspace.content.Bundle; import org.dspace.content.Collection; import org.dspace.content.Community; import org.dspace.content.DSpaceObject; import org.dspace.content.Item; import org.dspace.core.Constants; import org.dspace.core.Context; import org.dspace.handle.HandleManager; /** * Simple utility class for extracting handles. * * @author Scott Phillips */ public class HandleUtil { /** The URL prefix of all handle */ protected static final String HANDLE_PREFIX = "handle/"; protected static final String DSPACE_OBJECT = "dspace.object"; /** * Obtain the current DSpace handle for the specified request. * * @param objectModel * The cocoon model. * @return A DSpace handle, or null if none found. */ public static DSpaceObject obtainHandle(Map objectModel) throws SQLException { Request request = ObjectModelHelper.getRequest(objectModel); DSpaceObject dso = (DSpaceObject) request.getAttribute(DSPACE_OBJECT); if (dso == null) { String uri = request.getSitemapURI(); if (!uri.startsWith(HANDLE_PREFIX)) // Dosn't start with the prefix then no match return null; String handle = uri.substring(HANDLE_PREFIX.length()); int firstSlash = handle.indexOf('/'); if (firstSlash < 0) // If there is no first slash then no match return null; int secondSlash = handle.indexOf('/', firstSlash + 1); if (secondSlash < 0) // A trailing slash is not nesssary if there is nothing after // the handle. secondSlash = handle.length(); handle = handle.substring(0, secondSlash); Context context = ContextUtil.obtainContext(objectModel); dso = HandleManager.resolveToObject(context, handle); request.setAttribute(DSPACE_OBJECT, dso); } return dso; } /** * Determine if the given DSO is an ancestor of the the parent handle. * * @param dso * The child DSO object. * @param parent * The Handle to test against. * @return The matched DSO object or null if none found. */ public static boolean inheritsFrom(DSpaceObject dso, String parent) throws SQLException { DSpaceObject current = dso; while (current != null) { // Check if the current object has the handle we are looking for. if (current.getHandle().equals(parent)) return true; if (current.getType() == Constants.ITEM) { current = ((Item) current).getOwningCollection(); } else if (current.getType() == Constants.COLLECTION) { current = ((Collection) current).getCommunities()[0]; } else if (current.getType() == Constants.COMMUNITY) { current = ((Community) current).getParentCommunity(); } } // If the loop finished then we searched the entire parant-child chain // and did not find this handle, so the object was not found. return false; } /** * Build a list of trail metadata starting with the owning collection and * ending with the root level parent. If the Object is an item the item is * not included but all it's parents are. However if the item is a community * or collection then it is included along with all parents. * * @param dso * @param pageMeta */ public static void buildHandleTrail(DSpaceObject dso, PageMeta pageMeta, String contextPath) throws SQLException, WingException { // Add the trail back to the repository root. Stack<DSpaceObject> stack = new Stack<DSpaceObject>(); if (dso instanceof Bitstream) { Bitstream bitstream = (Bitstream) dso; Bundle[] bundles = bitstream.getBundles(); dso = bundles[0]; } if (dso instanceof Bundle) { Bundle bundle = (Bundle) dso; Item[] items = bundle.getItems(); dso = items[0]; } if (dso instanceof Item) { Item item = (Item) dso; Collection collection = item.getOwningCollection(); dso = collection; } if (dso instanceof Collection) { Collection collection = (Collection) dso; stack.push(collection); Community[] communities = collection.getCommunities(); dso = communities[0]; } if (dso instanceof Community) { Community community = (Community) dso; stack.push(community); for (Community parent : community.getAllParents()) { stack.push(parent); } } while (!stack.empty()) { DSpaceObject pop = stack.pop(); if (pop instanceof Collection) { Collection collection = (Collection) pop; String name = collection.getMetadata("name"); if (name == null || name.length() == 0) pageMeta.addTrailLink(contextPath + "/handle/" + pop.getHandle(), new Message("default","xmlui.general.untitled") ); else pageMeta.addTrailLink(contextPath + "/handle/" + pop.getHandle(), name); } else if (pop instanceof Community) { Community community = (Community) pop; String name = community.getMetadata("name"); if (name == null || name.length() == 0) pageMeta.addTrailLink(contextPath + "/handle/" + pop.getHandle(), new Message("default","xmlui.general.untitled") ); else pageMeta.addTrailLink(contextPath + "/handle/" + pop.getHandle(), name); } } } }