Package org.dspace.sword2

Source Code of org.dspace.sword2.SwordUrlManager

/**
* 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.sword2;

import org.apache.abdera.i18n.iri.IRI;
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.handle.HandleManager;
import org.dspace.core.ConfigurationManager;
import org.dspace.core.Context;
import org.swordapp.server.SwordError;

import java.sql.SQLException;
import java.net.URL;
import java.net.MalformedURLException;

/**
* @author Richard Jones
*
* Class responsible for constructing and de-constructing sword url space
* urls
*/
public class SwordUrlManager
{
  /** the sword configuration */
  private SwordConfigurationDSpace config;

  /** the active dspace context */
  private Context context;

  public SwordUrlManager(SwordConfigurationDSpace config, Context context)
  {
    this.config = config;
    this.context = context;
  }

  /**
   * Obtain the deposit URL for the given collection.  These URLs
   * should not be considered persistent, but will remain consistent
   * unless configuration changes are made to DSpace
   *
   * @param collection
   * @return  The Deposit URL
   * @throws DSpaceSwordException
   */
  public String getDepositLocation(Collection collection)
    throws DSpaceSwordException
  {
    return this.getBaseCollectionUrl() + "/" + collection.getHandle();
  }

  /**
   * Obtain the deposit URL for the given community.  These URLs
   * should not be considered persistent, but will remain consistent
   * unless configuration changes are made to DSpace
   *
   * @param community
   * @return  The Deposit URL
   * @throws DSpaceSwordException
   */
  public String getDepositLocation(Community community)
    throws DSpaceSwordException
  {
    if (this.config.allowCommunityDeposit())
    {
      return this.getBaseCollectionUrl() + "/" + community.getHandle();
    }
    return null;
  }

  public String getSwordBaseUrl()
      throws DSpaceSwordException
  {
    String sUrl = ConfigurationManager.getProperty("swordv2-server", "url");
    if (sUrl == null || "".equals(sUrl))
    {
      String dspaceUrl = ConfigurationManager.getProperty("dspace.baseUrl");
      if (dspaceUrl == null || "".equals(dspaceUrl))
      {
        throw new DSpaceSwordException("Unable to construct service document urls, due to missing/invalid " +
            "config in sword2.url and/or dspace.baseUrl");
      }

            try
            {
                URL url = new URL(dspaceUrl);
                sUrl = new URL(url.getProtocol(), url.getHost(), url.getPort(), "/swordv2").toString();
            }
            catch (MalformedURLException e)
            {
                throw new DSpaceSwordException("Unable to construct service document urls, due to invalid dspace.baseUrl " +
            e.getMessage(),e);
            }
    }
    return sUrl;
  }

    public Item getItem(Context context, String location)
            throws DSpaceSwordException, SwordError
    {
        try
    {
      String baseUrl = this.getSwordBaseUrl();
            String emBaseUrl = baseUrl + "/edit-media/";
      String eBaseUrl = baseUrl + "/edit/";
      String sBaseUrl = baseUrl + "/statement/";
      String cBaseUrl = null;
      if (location.startsWith(emBaseUrl))
      {
        cBaseUrl = emBaseUrl;
      }
      else if (location.startsWith(eBaseUrl))
      {
        cBaseUrl = eBaseUrl;
      }
      else if (location.startsWith(sBaseUrl))
      {
        cBaseUrl = sBaseUrl;
      }
            else
            {
        throw new SwordError(DSpaceUriRegistry.BAD_URL, "The item URL is invalid");
      }

            String iid = location.substring(cBaseUrl.length());
            if (iid.endsWith(".atom"))
            {
                // this is the atom url, so we need to strip that to ge tthe item id
                iid = iid.substring(0, iid.length() - ".atom".length());
            }
      else if (iid.endsWith(".rdf"))
      {
        // this is the rdf url so we need to strip that to get the item id
        iid = iid.substring(0, iid.length() - ".rdf".length());
      }
     
            int itemId = Integer.parseInt(iid);
            Item item = Item.find(context, itemId);
      return item;
    }
    catch (SQLException e)
    {
      // log.error("Caught exception:", e);
      throw new DSpaceSwordException("There was a problem resolving the item", e);
    }
    }

  public String getTypeSuffix(Context context, String location)
  {
    String tail = location.substring(location.lastIndexOf("/"));
    int typeSeparator = tail.lastIndexOf(".");
    if (typeSeparator == -1)
    {
      return null;
    }
    return tail.substring(typeSeparator + 1);
  }

    public boolean isFeedRequest(Context context, String url)
    {
        return url.endsWith(".atom");
    }

  /**
   * Obtain the collection which is represented by the given
   * URL
   *
   * @param context  the DSpace context
   * @param location  the URL to resolve to a collection
   * @return    The collection to which the url resolves
   * @throws DSpaceSwordException
   */
  // FIXME: we need to generalise this to DSpaceObjects, so that we can support
  // Communities, Collections and Items separately
  public Collection getCollection(Context context, String location)
    throws DSpaceSwordException, SwordError
  {
    try
    {
      String baseUrl = this.getBaseCollectionUrl();
      if (baseUrl.length() == location.length())
      {
        throw new SwordError(DSpaceUriRegistry.BAD_URL, "The deposit URL is incomplete");
      }
      String handle = location.substring(baseUrl.length());
      if (handle.startsWith("/"))
      {
        handle = handle.substring(1);
      }
      if ("".equals(handle))
      {
        throw new SwordError(DSpaceUriRegistry.BAD_URL, "The deposit URL is incomplete");
      }

      DSpaceObject dso = HandleManager.resolveToObject(context, handle);
            if (dso == null)
            {
                return null;
            }

      if (!(dso instanceof Collection))
      {
        throw new SwordError(DSpaceUriRegistry.BAD_URL, "The deposit URL does not resolve to a valid collection");
      }

      return (Collection) dso;
    }
    catch (SQLException e)
    {
      // log.error("Caught exception:", e);
      throw new DSpaceSwordException("There was a problem resolving the collection", e);
    }
  }

  /**
   * Construct the service document URL for the given object, which will
   * be supplied in the sword:service element of other service document
   * entries.
   *
   * @param community
   * @throws DSpaceSwordException
   */
  public String constructSubServiceUrl(Community community)
      throws DSpaceSwordException
  {
    String base = this.getBaseServiceDocumentUrl();
    String handle = community.getHandle();
    return base + "/" + handle;
  }

  /**
   * Construct the service document URL for the given object, which will
   * be supplied in the sword:service element of other service document
   * entries.
   *
   * @param collection
   * @throws DSpaceSwordException
   */
  public String constructSubServiceUrl(Collection collection)
      throws DSpaceSwordException
  {
    String base = this.getBaseServiceDocumentUrl();
    String handle = collection.getHandle();
    return base + "/" + handle;
  }

  /**
   * Extract a DSpaceObject from the given URL.  If this method is unable to
   * locate a meaningful and appropriate DSpace object it will throw the
   * appropriate SWORD error.
   * @param url
   * @throws DSpaceSwordException
   * @throws SwordError
   */
  public DSpaceObject extractDSpaceObject(String url)
      throws DSpaceSwordException, SwordError
  {
    try
    {
      String sdBase = this.getBaseServiceDocumentUrl();
      // String mlBase = this.getBaseMediaLinkUrl();

      if (url.startsWith(sdBase))
      {
        // we are dealing with a service document request
       
        // first, let's find the beginning of the handle
        url = url.substring(sdBase.length());
        if (url.startsWith("/"))
        {
          url = url.substring(1);
        }
        if (url.endsWith("/"))
        {
          url = url.substring(0, url.length() - 1);
        }

        DSpaceObject dso = HandleManager.resolveToObject(context, url);
                if (dso == null)
                {
                    return null;
                }
        else if (dso instanceof Collection || dso instanceof Community)
        {
          return dso;
        }
        else
        {
          throw new SwordError(DSpaceUriRegistry.BAD_URL,
              "Service Document request does not refer to a DSpace Collection or Community");
        }
      }
      else
      {
        throw new SwordError(DSpaceUriRegistry.BAD_URL,
            "Unable to recognise URL as a valid service document: " + url);
      }
    }
    catch (SQLException e)
    {
      throw new DSpaceSwordException(e);
    }
  }

  /**
   * Get the base URL for service document requests.
   *
   * @throws DSpaceSwordException
   */
  public String getBaseServiceDocumentUrl()
      throws DSpaceSwordException
  {
    String sdUrl = ConfigurationManager.getProperty("swordv2-server", "servicedocument.url");
    if (sdUrl == null || "".equals(sdUrl))
    {
      String dspaceUrl = ConfigurationManager.getProperty("dspace.baseUrl");
      if (dspaceUrl == null || "".equals(dspaceUrl))
      {
        throw new DSpaceSwordException("Unable to construct service document urls, due to missing/invalid " +
            "config in swordv2-server.cfg servicedocument.url and/or dspace.baseUrl");
      }

            try
            {
                URL url = new URL(dspaceUrl);
                sdUrl = new URL(url.getProtocol(), url.getHost(), url.getPort(), "/swordv2/servicedocument").toString();
            }
            catch (MalformedURLException e)
            {
                throw new DSpaceSwordException("Unable to construct service document urls, due to invalid dspace.baseUrl " +
            e.getMessage(),e);
            }
    }
    return sdUrl;
  }

  /**
   * Get the base deposit URL for the DSpace SWORD implementation.  This
   * is effectively the URL of the servlet which deals with deposit
   * requests, and is used as the basis for the individual Collection
   * URLs
   *
   * If the configuration sword.deposit.url is set, this will be returned,
   * but if not, it will construct the url as follows:
   *
   * [dspace.baseUrl]/sword/deposit
   *
   * where dspace.baseUrl is also in the configuration file.
   *
   * @return  the base URL for sword deposit
   * @throws DSpaceSwordException
   */
  public String getBaseCollectionUrl()
    throws DSpaceSwordException
  {
    String depositUrl = ConfigurationManager.getProperty("swordv2-server", "collection.url");
    if (depositUrl == null || "".equals(depositUrl))
    {
      String dspaceUrl = ConfigurationManager.getProperty("dspace.baseUrl");
      if (dspaceUrl == null || "".equals(dspaceUrl))
      {
        throw new DSpaceSwordException("Unable to construct deposit urls, due to missing/invalid config in " +
            "swordv2-server.cfg deposit.url and/or dspace.baseUrl");
      }

            try
            {
                URL url = new URL(dspaceUrl);
                depositUrl = new URL(url.getProtocol(), url.getHost(), url.getPort(), "/swordv2/collection").toString();
            }
            catch (MalformedURLException e)
            {
                throw new DSpaceSwordException("Unable to construct deposit urls, due to invalid dspace.baseUrl " +
            e.getMessage(),e);
            }


    }
    return depositUrl;
  }

  /**
   * Is the given URL the base service document URL?
   *
   * @param url
   * @throws DSpaceSwordException
   */
  public boolean isBaseServiceDocumentUrl(String url)
      throws DSpaceSwordException
  {
    return this.getBaseServiceDocumentUrl().equals(url);
  }

  /**
   * Central location for constructing usable URLs for DSpace bitstreams.
   * There is no place in the main DSpace code base for doing this.
   *
   * @param bitstream
   * @throws DSpaceSwordException
   */
  public String getBitstreamUrl(Bitstream bitstream)
      throws DSpaceSwordException
  {
    try
    {
      Bundle[] bundles = bitstream.getBundles();
      Bundle parent = null;
      if (bundles.length > 0)
      {
        parent = bundles[0];
      }
      else
      {
        throw new DSpaceSwordException("Encountered orphaned bitstream");
      }

      Item[] items = parent.getItems();
      Item item;
      if (items.length > 0)
      {
        item = items[0];
      }
      else
      {
        throw new DSpaceSwordException("Encountered orphaned bundle");
      }

      String handle = item.getHandle();
      String bsLink = ConfigurationManager.getProperty("dspace.url");

      if (handle != null && !"".equals(handle))
      {
        bsLink = bsLink + "/bitstream/" + handle + "/" + bitstream.getSequenceID() + "/" + bitstream.getName();
      }
      else
      {
        bsLink = bsLink + "/retrieve/" + bitstream.getID() + "/" + bitstream.getName();
      }

      return bsLink;
    }
    catch (SQLException e)
    {
      throw new DSpaceSwordException(e);
    }
  }

  public String getActionableBitstreamUrl(Bitstream bitstream)
      throws DSpaceSwordException
  {
    return this.getSwordBaseUrl() + "/edit-media/bitstream/" + bitstream.getID() + "/" + bitstream.getName();
  }

  public boolean isActionableBitstreamUrl(Context context, String url)
  {
    return url.contains("/edit-media/bitstream/");
  }

  public Bitstream getBitstream(Context context, String location)
      throws DSpaceSwordException, SwordError
  {
    try
    {
      String baseUrl = this.getSwordBaseUrl();
            String emBaseUrl = baseUrl + "/edit-media/bitstream/";
      if (!location.startsWith(emBaseUrl))
      {
        throw new SwordError(DSpaceUriRegistry.BAD_URL, "The bitstream URL is invalid");
      }

            String bitstreamParts = location.substring(emBaseUrl.length());

      // the bitstream id is the part up to the first "/"
      int firstSlash = bitstreamParts.indexOf("/");
      int bid = Integer.parseInt(bitstreamParts.substring(0, firstSlash));
      String fn = bitstreamParts.substring(firstSlash + 1);

            Bitstream bitstream = Bitstream.find(context, bid);
      return bitstream;
    }
    catch (SQLException e)
    {
      // log.error("Caught exception:", e);
      throw new DSpaceSwordException("There was a problem resolving the collection", e);
    }
  }

  // FIXME: we need a totally new kind of URL scheme; perhaps we write the identifier into the item
  public String getAtomStatementUri(Item item)
      throws DSpaceSwordException
  {
    return this.getSwordBaseUrl() + "/statement/" + item.getID() + ".atom";
  }

  public String getOreStatementUri(Item item)
      throws DSpaceSwordException
  {
    return this.getSwordBaseUrl() + "/statement/" + item.getID() + ".rdf";
  }

  public String getAggregationUrl(Item item)
      throws DSpaceSwordException
  {
    return this.getOreStatementUri(item) + "#aggregation";
  }

  public IRI getEditIRI(Item item)
      throws DSpaceSwordException
  {
    return new IRI(this.getSwordBaseUrl() + "/edit/" + item.getID());
  }

  public String getSplashUrl(Item item)
      throws DSpaceSwordException
  {
    WorkflowTools wft = new WorkflowTools();

        // if the item is in the workspace, we need to give it it's own
        // special identifier
        if (wft.isItemInWorkspace(context, item))
        {
            String urlTemplate = ConfigurationManager.getProperty("swordv2-server", "workspace.url-template");
            if (urlTemplate != null)
            {
                return urlTemplate.replace("#wsid#", Integer.toString(wft.getWorkspaceItem(context, item).getID()));
            }
        }
        // otherwise, it may be in the workflow, in which case there is
        // no identifier
        else if (wft.isItemInWorkflow(context, item))
        {
            // do nothing
            return null;
        }
        // finally, otherwise we need to just return the handle of the
        // item
        else
        {
        return HandleManager.getCanonicalForm(item.getHandle());
        }
        return null;
  }

  public IRI getContentUrl(Item item)
      throws DSpaceSwordException
  {
    return new IRI(this.getSwordBaseUrl() + "/edit-media/" + item.getID());
  }

    public IRI getMediaFeedUrl(Item item)
      throws DSpaceSwordException
  {
    return new IRI(this.getSwordBaseUrl() + "/edit-media/" + item.getID() + ".atom");
  }
}
TOP

Related Classes of org.dspace.sword2.SwordUrlManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.