/**
   * Get an array of all the collections that the current SWORD context will allow deposit onto in
   * the given DSpace context
   *
   * <p>The user may submit to a community if the following conditions are met:
   *
   * <p>IF: the authenticated user is an administrator AND: (the on-behalf-of user is an
   * administrator OR the on-behalf-of user is authorised to READ OR the on-behalf-of user is null)
   * OR IF: the authenticated user is authorised to READ AND: (the on-behalf-of user is an
   * administrator OR the on-behalf-of user is authorised to READ OR the on-behalf-of user is null)
   *
   * @param community
   * @return the array of allowed collections
   * @throws DSpaceSwordException
   */
  public List<Community> getCommunities(SwordContext swordContext, Community community)
      throws DSpaceSwordException {
    // a community is allowed if the following conditions are met
    //
    // - the authenticated user is an administrator
    // -- the on-behalf-of user is an administrator
    // -- the on-behalf-of user is authorised to READ
    // -- the on-behalf-of user is null
    // - the authenticated user is authorised to READ
    // -- the on-behalf-of user is an administrator
    // -- the on-behalf-of user is authorised to READ
    // -- the on-behalf-of user is null
    try {
      Community[] comms = community.getSubcommunities();
      List<Community> allowed = new ArrayList<Community>();

      for (int i = 0; i < comms.length; i++) {
        boolean authAllowed = false;
        boolean oboAllowed = false;

        // check for obo null
        if (swordContext.getOnBehalfOf() == null) {
          oboAllowed = true;
        }

        // look up the READ policy on the community.  This will include determining if the user is
        // an administrator
        // so we do not need to check that separately
        if (!authAllowed) {
          authAllowed =
              AuthorizeManager.authorizeActionBoolean(
                  swordContext.getAuthenticatorContext(), comms[i], Constants.READ);
        }

        // if we have not already determined that the obo user is ok to submit, look up the READ
        // policy on the
        // community.  THis will include determining if the user is an administrator.
        if (!oboAllowed) {
          oboAllowed =
              AuthorizeManager.authorizeActionBoolean(
                  swordContext.getOnBehalfOfContext(), comms[i], Constants.READ);
        }

        // final check to see if we are allowed to READ
        if (authAllowed && oboAllowed) {
          allowed.add(comms[i]);
        }
      }
      return allowed;

    } catch (SQLException e) {
      log.error("Caught exception: ", e);
      throw new DSpaceSwordException(e);
    }
  }
  public static void applyFiltersCommunity(Context c, Community community) throws Exception {
    Community[] subcommunities = community.getSubcommunities();
    for (int i = 0; i < subcommunities.length; i++) {
      applyFiltersCommunity(c, subcommunities[i]);
    }

    Collection[] collections = community.getCollections();
    for (int j = 0; j < collections.length; j++) {
      applyFiltersCollection(c, collections[j]);
    }
  }
  /**
   * Get a preserved community backup file and respective children from cloud.
   *
   * @param context context DSpace
   * @param ref ID of the community
   * @param establishConnection true if pretend establish connection to cloud
   * @return true if file correctly sent to cloud, or false if not
   */
  public Boolean getCommunityAndChilds(Context context, Integer ref, Boolean establishConnection) {
    // if true make the connection available
    if (establishConnection == true) {
      this.makeConnection();
      this.filesInCloud.putAll(this.newCloudConnection.getInfoFilesIn(Constants.COMMUNITY));
    }

    // get file community from cloud
    getCommunity(context, ref, false);

    Community obj;
    Community[] subCommunities;
    Collection[] collections;

    // get community and the respective sub-communities and childs
    try {
      obj = Community.find(context, ref);
      subCommunities = obj.getSubcommunities();
      collections = obj.getCollections();
    } catch (Exception ex) {
      // it means it is the first father in the order, so close connection
      if (establishConnection == true) this.closeConnection();
      Logger.getLogger(ActualContentManagement.class.getName()).log(Level.SEVERE, null, ex);
      return false;
    }

    // get from cloud all the respective files sub-communities and childs
    if (subCommunities.length != 0) {
      for (int i = 0; i < subCommunities.length; i++)
        getCommunityAndChilds(context, subCommunities[i].getID(), false);
    }

    // get from cloud all files collections and childs
    if (collections.length != 0) {
      for (int i = 0; i < collections.length; i++)
        getCollectionAndChilds(context, collections[i].getID(), false);
    }

    // it means it is the first father in the order
    if (establishConnection == true) this.closeConnection();

    return true;
  }
  public void defiliate(Context c, Community parent, Community child)
      throws SQLException, AuthorizeException, IOException {
    // verify that child is indeed a child of parent
    Community[] parentKids = parent.getSubcommunities();
    boolean isChild = false;

    for (int i = 0; i < parentKids.length; i++) {
      if (parentKids[i].getID() == child.getID()) {
        isChild = true;

        break;
      }
    }

    if (!isChild) {
      System.out.println("Error, child community not a child of parent community");
      System.exit(1);
    }

    // OK remove the mappings - but leave the community, which will become
    // top-level
    DatabaseManager.updateQuery(
        c,
        "DELETE FROM community2community WHERE parent_comm_id= ? " + "AND child_comm_id= ? ",
        parent.getID(),
        child.getID());

    // complete the pending transaction
    c.complete();
    System.out.println(
        "Defiliation complete. Community: '"
            + child.getID()
            + "' is no longer a child of community: '"
            + parent.getID()
            + "'");
  }