/**
   * addLink
   *
   * <p>Create a link between two items
   *
   * <pre>
   * Version	Date		Developer				Description
   * 0.1		26/04/2012	Genevieve Turner (GT)	Initial
   * 0.19		27/09/2012	Genevieve Turner (GT)	Updated to generate reverse links
   * </pre>
   *
   * @param fedoraObject The item to transform to a display
   * @param form Contains the parameters from the request
   * @return A response for the web page
   * @throws FedoraClientException
   */
  @Override
  public void addLink(FedoraObject fedoraObject, String linkType, String itemId)
      throws FedoraClientException {
    String link = GlobalProps.getProperty(GlobalProps.PROP_FEDORA_RELATEDURI);

    LinkTypeDAO linkTypeDAO = new LinkTypeDAOImpl();
    LinkType linkTypeRecord = linkTypeDAO.getByCode(linkType);
    if (null == linkTypeRecord) {
      throw new WebApplicationException(
          Response.status(400).entity("Invalid relation type").build());
    }

    FedoraReference reference = new FedoraReference();
    String referenceType = linkType;
    String referenceItem = itemId;
    reference.setPredicate_(link + referenceType);
    reference.setObject_(referenceItem);
    reference.setIsLiteral_(Boolean.FALSE);
    FedoraBroker.addRelationship(fedoraObject.getObject_id(), reference);

    if (referenceItem.startsWith("info:fedora/")) {
      String referenceItemID = referenceItem.substring(12);
      FedoraReference reverseReference = new FedoraReference();
      reverseReference.setPredicate_(link + linkTypeRecord.getReverse());
      reverseReference.setObject_("info:fedora/" + fedoraObject.getObject_id());
      reverseReference.setIsLiteral_(Boolean.FALSE);
      FedoraBroker.addRelationship(referenceItemID, reverseReference);
    }
  }
  /**
   * getPage
   *
   * <p>Retrieves a page for the given values
   *
   * <pre>
   * Version	Date		Developer				Description
   * 0.1		26/04/2012	Genevieve Turner (GT)	Initial
   * 0.2		03/05/2012	Genevieve Turner (GT)	Updated to add related links to the page
   * 0.8		20/06/2012	Genevieve Turner (GT)	Updated so that page retrieval is now using a map
   * 0.10		11/07/2012	Genevieve Turner (GT)	Updated to allow or deny access to unpublished pages
   * 0.11		13/07/2012	Rahul Khanna (RK)		Updated filelist displayed on collection page
   * 0.15		20/08/2012	Genevieve Turner (GT)	Updated to use permissionService rather than aclService
   * 0.23		13/11/2012	Genevieve Turner (GT)	Added whether edit mode should be used in retrieving the page (i.e. no published information is retrieved)
   * </pre>
   *
   * @param layout The layout to use with display (i.e. the xsl stylesheet)
   * @param tmplt The template that determines the fields on the screen
   * @param fedoraObject The object of the page to retrieve
   * @param editMode Indicates whether published information should be returned or not
   * @return Returns the viewable for the jsp file to pick up.
   */
  private Map<String, Object> getPage(
      String layout, String template, FedoraObject fedoraObject, boolean editMode) {
    boolean hasPermission = false;
    if (fedoraObject == null) {
      hasPermission = true;
    } else {
      hasPermission = permissionService.checkViewPermission(fedoraObject);
    }
    Map<String, Object> values = new HashMap<String, Object>();
    values.put("topage", "/page.jsp");
    ViewTransform viewTransform = new ViewTransform();
    try {
      if (fedoraObject != null) {
        // Add bag summary to model.
        try {
          RecordDataSummary rdi =
              storageController.getRecordDataSummary(fedoraObject.getObject_id());
          values.put("rdi", rdi);
        } catch (IOException | StorageException e) {
          LOGGER.error(e.getMessage(), e);
        }
      }
      if (hasPermission) {
        values.putAll(viewTransform.getPage(layout, template, fedoraObject, null, editMode, false));
      } else if (fedoraObject.getPublished()) {
        values.putAll(viewTransform.getPage(layout, template, fedoraObject, null, false, true));
      } else {
        throw new AccessDeniedException(
            format(
                "User does not have permission to view page for record {0}",
                fedoraObject.getObject_id()));
      }
    } catch (FedoraClientException e) {
      LOGGER.error("Exception: ", e);
      values.put("topage", "/error.jsp");
    }

    if (!values.containsKey("page")) {
      values.put("topage", "/error.jsp");
    }

    if (fedoraObject != null) {
      // TODO This is should probably be modified
      values.put("fedoraObject", fedoraObject);

      String sidepage = "buttons.jsp";
      values.put("sidepage", sidepage);

      // SparqlResultSet resultSet = getLinks(fedoraObject);
      List<Result> resultSet = getLinks(fedoraObject);
      values.put("resultSet", resultSet);
    }

    return values;
  }
 /**
  * delete
  *
  * <p>Set the status of the given object to deleted
  *
  * @param fedoraObject The fedora object
  * @throws FedoraClientException
  */
 public void delete(FedoraObject fedoraObject) throws FedoraClientException {
   FedoraBroker.updateObjectState(fedoraObject.getObject_id(), "D");
   // Add this as a work around for the fact that commitWithin does not seem to work for
   // the Solr XML delete so we want to commit after delete
   SolrServer solrServer = SolrManager.getInstance().getSolrServer();
   try {
     solrServer.deleteById(fedoraObject.getObject_id(), 5000);
   } catch (IOException e) {
     LOGGER.debug("Exception committing delete", e);
   } catch (SolrServerException e) {
     LOGGER.debug("Exception committing delete", e);
   }
 }
  /**
   * getListInformation
   *
   * <p>Retrieves some information about the list of fedora objects.
   *
   * <pre>
   * Version	Date		Developer				Description
   * 0.14		26/07/2012	Genevieve Turner(GT)	Initial
   * </pre>
   *
   * @param fedoraObjects A list of fedora objects to get more information for
   * @return Returns a list of fedora objects
   * @see
   *     au.edu.anu.datacommons.security.service.FedoraObjectService#getListInformation(java.util.List)
   */
  @Override
  public List<Result> getListInformation(List<FedoraObject> fedoraObjects) {
    if (fedoraObjects.size() == 0) {
      return null;
    }
    // Create the sparql query
    SparqlQuery sparqlQuery = new SparqlQuery();
    sparqlQuery.addVar("?id");
    sparqlQuery.addVar("?name");
    sparqlQuery.addTriple("?item", "<dc:identifier>", "?id", Boolean.FALSE);
    sparqlQuery.addTriple("?item", "<dc:title>", "?name", Boolean.FALSE);
    // Ensure that the linked to item is active (i.e. it hasn't been deleted)
    sparqlQuery.addTriple("?item", "<fedora-model:state>", "<fedora-model:Active>", Boolean.FALSE);
    StringBuffer queryFilter = new StringBuffer();
    for (FedoraObject fedoraObject : fedoraObjects) {
      if (queryFilter.length() > 0) {
        queryFilter.append(" || ");
      }
      queryFilter.append("?id = '");
      queryFilter.append(fedoraObject.getObject_id());
      queryFilter.append("' ");
    }
    sparqlQuery.addFilter(queryFilter.toString(), "");

    ClientResponse clientResponse = riSearchService.post("query", sparqlQuery.generateQuery());

    List<Result> resultList = getSparqlResultList(clientResponse);
    return resultList;
  }
 /**
  * getItemByName
  *
  * <p>Gets the fedora object given the pid
  *
  * <pre>
  * Version	Date		Developer				Description
  * 0.1		26/04/2012	Genevieve Turner (GT)	Initial
  * 0.2		02/05/2012	Genevieve Turner (GT)	Updated to fix issue with url encoded pid
  * 0.3		08/05/2012	Genevieve Turner (GT)	Updated to use newly created util decode function
  * </pre>
  *
  * @param id The fedora object pid
  * @return Returns the FedoraObject of the given pid
  */
 @Override
 public FedoraObject getItemByPid(String pid) {
   String decodedPid = null;
   decodedPid = Util.decodeUrlEncoded(pid);
   if (decodedPid == null) {
     return null;
   }
   FedoraObjectDAOImpl object = new FedoraObjectDAOImpl();
   FedoraObject item = object.getSingleByName(decodedPid);
   if (item != null) {
     LOGGER.trace("Retrieved item {}", item.getObject_id());
   }
   return item;
 }
  /**
   * getLinks
   *
   * <p>Retrieves the links for a page.
   *
   * <pre>
   * Version	Date		Developer				Description
   * 0.3		26/04/2012	Genevieve Turner (GT)	Initial
   * 0.7		08/06/2012	Genevieve Turner (GT)	Updated to cater for change to post method in the riSearchService
   * 0.17		28/08/2012	Genevieve Turner (GT)	Added the display of reverse links
   * 0.19		28/09/2012	Genevieve Turner (GT)	Updated so reverse links are not displayed
   * 0.21		22/10/2012	Genevieve Turner (GT)	Made this method public
   * </pre>
   *
   * @param fedoraObject The object to retrieve the links for
   * @return The results of the query
   */
  @Override
  public List<Result> getLinks(FedoraObject fedoraObject) {
    SparqlQuery sparqlQuery = new SparqlQuery();

    sparqlQuery.addVar("?item");
    sparqlQuery.addVar("?title");
    sparqlQuery.addVar("?predicate");
    sparqlQuery.addVar("?type");

    sparqlQuery.addTriple(
        "<info:fedora/" + fedoraObject.getObject_id() + ">", "?predicate", "?item", Boolean.FALSE);
    // GT - 20120928 - Note this code is only commented out as it may be placed back in at a later
    // date.
    /*
    StringBuilder tripleString = new StringBuilder();
    tripleString.append("{ <info:fedora/");
    tripleString.append(fedoraObject.getObject_id());
    tripleString.append("> ?predicate ?item . } ");
    tripleString.append("UNION ");
    tripleString.append("{ ?item ?predicate <info:fedora/");
    tripleString.append(fedoraObject.getObject_id());
    tripleString.append("> } ");

    sparqlQuery.addTripleSet(tripleString.toString());
    */
    // Ensure that the linked to item is active (i.e. it hasn't been deleted)
    sparqlQuery.addTriple("?item", "<dc:title>", "?title", true);
    sparqlQuery.addTriple("?item", "<dc:type>", "?type", true);
    sparqlQuery.addTriple("?item", "<fedora-model:state>", "?state", true);
    String filterString =
        "regex(str(?predicate), '"
            + GlobalProps.getProperty(GlobalProps.PROP_FEDORA_RELATEDURI)
            + "', 'i')";
    sparqlQuery.addFilter(filterString, "");
    sparqlQuery.addFilter("!BOUND(?state) || regex(str(?state), 'Active')", "&&");
    ClientResponse respFromRiSearch = riSearchService.post("query", sparqlQuery.generateQuery());

    List<Result> resultList = getSparqlResultList(respFromRiSearch);
    LOGGER.debug("Number of related items found: {}", resultList.size());
    return resultList;
  }