/**
   * @param folder This is the folder where the assets are stored
   * @param fileAssetsList This is the list of all the file assets
   * @return
   */
  private static List<String> findFileAssetsList(File folder, List<String> fileAssetsList) {
    File[] files = folder.listFiles();
    if (0 < files.length) {
      List<Structure> structures = StructureFactory.getStructures();
      List<Field> binaryFields = new ArrayList<Field>();
      List<Field> fields;
      for (Structure structure : structures) {
        fields = FieldsCache.getFieldsByStructureInode(structure.getInode());

        for (Field field : fields) {
          if (field.getFieldType().equals(Field.FieldType.BINARY.toString()))
            binaryFields.add(field);
        }
      }

      boolean isBinaryField;
      for (int j = 0; j < files.length; j++) {
        fileAssetsList.add(files[j].getPath());
        if (files[j].isDirectory()) {

          isBinaryField = false;
          for (Field field : binaryFields) {
            if (field.getVelocityVarName().equals(files[j].getName())) {
              isBinaryField = true;
              break;
            }
          }

          if (!isBinaryField) findFileAssetsList(files[j], fileAssetsList);
        }
      }
    }
    return fileAssetsList;
  }
  private void _defaultStructure(ActionForm form, ActionRequest req, ActionResponse res) {
    try {

      Structure structure = (Structure) req.getAttribute(WebKeys.Structure.STRUCTURE);

      User user = _getUser(req);
      HttpServletRequest httpReq = ((ActionRequestImpl) req).getHttpServletRequest();
      _checkWritePermissions(structure, user, httpReq);

      StructureFactory.disableDefault();
      structure.setDefaultStructure(true);
      StructureFactory.saveStructure(structure);
      String message = "message.structure.defaultstructure";
      SessionMessages.add(req, "message", message);
    } catch (Exception ex) {
      Logger.debug(EditStructureAction.class, ex.toString());
    }
  }
  @SuppressWarnings("deprecation")
  private Structure _loadStructure(ActionForm form, ActionRequest req, ActionResponse res)
      throws ActionException, DotDataException {

    User user = _getUser(req);
    Structure structure = new Structure();
    String inodeString = req.getParameter("inode");
    if (InodeUtils.isSet(inodeString)) {
      /*
       * long inode = Long.parseLong(inodeString); if (inode != 0) {
       * structure = StructureFactory.getStructureByInode(inode); }
       */

      if (InodeUtils.isSet(inodeString)) {
        structure = StructureFactory.getStructureByInode(inodeString);
      }
    }
    req.setAttribute(WebKeys.Structure.STRUCTURE, structure);

    boolean searchable = false;

    List<Field> fields = structure.getFields();
    for (Field f : fields) {
      if (f.isIndexed()) {
        searchable = true;
        break;
      }
    }

    if (!searchable && InodeUtils.isSet(structure.getInode())) {
      String message = "warning.structure.notsearchable";
      SessionMessages.add(req, "message", message);
    }

    if (structure.isFixed()) {
      String message = "warning.object.isfixed";
      SessionMessages.add(req, "message", message);
    }

    // Checking permissions
    _checkUserPermissions(structure, user, PermissionAPI.PERMISSION_READ);

    return structure;
  }
  protected void _loadStructures(
      RenderRequest req, User user, String countWebKey, String viewWebKey, String queryWebKey)
      throws Exception {

    com.liferay.portlet.RenderRequestImpl reqImpl = (com.liferay.portlet.RenderRequestImpl) req;
    HttpServletRequest httpReq = reqImpl.getHttpServletRequest();
    // gets the session object for the messages
    HttpSession session = httpReq.getSession();

    Integer structureType =
        (Integer) session.getAttribute(com.dotmarketing.util.WebKeys.Structure.STRUCTURE_EDIT_TYPE);
    if (req.getParameter("structureType") != null)
      structureType = Integer.parseInt(req.getParameter("structureType"));
    if (structureType != null)
      session.setAttribute(
          com.dotmarketing.util.WebKeys.Structure.STRUCTURE_EDIT_TYPE, structureType);

    String query = req.getParameter("query");
    String resetQuery = req.getParameter("resetQuery");

    List<Structure> structures = new java.util.ArrayList<Structure>();

    try {
      String orderby = req.getParameter("orderBy");
      if (!UtilMethods.isSet(orderby)) {
        orderby = "upper(name)";
      }
      String direction = req.getParameter("direction");
      if (!UtilMethods.isSet(direction)) {
        direction = "asc";
      }

      int pageNumber = 1;

      if (UtilMethods.isSet(req.getParameter("pageNumber"))) {
        pageNumber = Integer.parseInt(req.getParameter("pageNumber"));
      }

      int limit = com.dotmarketing.util.Config.getIntProperty("PER_PAGE");

      int offset = (pageNumber - 1) * limit;

      if ((query == null) && (resetQuery == null)) {
        query = (String) session.getAttribute(queryWebKey);
      }
      session.setAttribute(queryWebKey, query);

      int count = 0;
      String queryCondition = "";

      if (((query != null) && (query.length() != 0)) || (structureType != null)) {

        if (query == null) query = "";
        query = query.trim();
        if (UtilMethods.isSet(query)) {
          queryCondition +=
              "(lower(name) "
                  + "like '%"
                  + query.toLowerCase().replace("\'", "\\\'")
                  + "%' or inode='"
                  + query
                  + "')";
        }

      } else {
        Logger.debug(this, "Getting all Forms Structures");
      }

      if (UtilMethods.isSet(queryCondition)) {
        queryCondition += " and structuretype=" + Structure.STRUCTURE_TYPE_FORM;
      } else {
        queryCondition += " structuretype=" + Structure.STRUCTURE_TYPE_FORM;
      }

      structures =
          StructureFactory.getStructuresByUser(
              user, queryCondition, orderby, limit, offset, direction);
      count = (int) ((PaginatedArrayList<Structure>) structures).getTotalResults();
      req.setAttribute(countWebKey, new Integer(count));
      req.setAttribute(viewWebKey, structures);
    } catch (Exception e) {
      req.setAttribute(viewWebKey, structures);
      Logger.error(this, "Exception e =" + e.getMessage(), e);
      throw new Exception(e.getMessage());
    }
  }
  private void _deleteStructure(ActionForm form, ActionRequest req, ActionResponse res)
      throws Exception {

    try {
      Structure structure = (Structure) req.getAttribute(WebKeys.Structure.STRUCTURE);

      User user = _getUser(req);
      HttpServletRequest httpReq = ((ActionRequestImpl) req).getHttpServletRequest();

      // Checking permissions
      _checkDeletePermissions(structure, user, httpReq);

      // checking if there is containers using this structure
      List<Container> containers =
          APILocator.getContainerAPI().findContainersForStructure(structure.getInode());
      if (containers.size() > 0) {
        StringBuilder names = new StringBuilder();
        for (int i = 0; i < containers.size(); i++)
          names.append(containers.get(i).getFriendlyName()).append(", ");
        Logger.warn(
            EditStructureAction.class,
            "Structure "
                + structure.getName()
                + " can't be deleted because the following containers are using it: "
                + names);
        SessionMessages.add(req, "message", "message.structure.notdeletestructure.container");
        return;
      }

      if (!structure.isDefaultStructure()) {

        @SuppressWarnings("rawtypes")
        List fields = FieldFactory.getFieldsByStructure(structure.getInode());

        @SuppressWarnings("rawtypes")
        Iterator fieldsIter = fields.iterator();

        while (fieldsIter.hasNext()) {
          Field field = (Field) fieldsIter.next();
          FieldFactory.deleteField(field);
        }

        int limit = 200;
        int offset = 0;
        List<Contentlet> contentlets =
            conAPI.findByStructure(structure, user, false, limit, offset);
        int size = contentlets.size();
        while (size > 0) {
          conAPI.delete(contentlets, user, false);
          contentlets = conAPI.findByStructure(structure, user, false, limit, offset);
          size = contentlets.size();
        }

        if (structure.getStructureType() == Structure.STRUCTURE_TYPE_FORM) {

          @SuppressWarnings({"deprecation", "static-access"})
          Structure st =
              StructureCache.getStructureByName(fAPI.FORM_WIDGET_STRUCTURE_NAME_FIELD_NAME);

          if (UtilMethods.isSet(st) && UtilMethods.isSet(st.getInode())) {

            @SuppressWarnings({"deprecation", "static-access"})
            Field field = st.getField(fAPI.FORM_WIDGET_FORM_ID_FIELD_NAME);

            List<Contentlet> widgetresults =
                conAPI.search(
                    "+structureInode:"
                        + st.getInode()
                        + " +"
                        + field.getFieldContentlet()
                        + ":"
                        + structure.getInode(),
                    0,
                    0,
                    "",
                    user,
                    false);
            if (widgetresults.size() > 0) {
              conAPI.delete(widgetresults, user, false);
            }
          }
        }

        // http://jira.dotmarketing.net/browse/DOTCMS-6435
        if (structure.getStructureType() == Structure.STRUCTURE_TYPE_FILEASSET) {
          StructureFactory.updateFolderFileAssetReferences(structure);
        }

        List<Relationship> relationships = RelationshipFactory.getRelationshipsByParent(structure);
        for (Relationship rel : relationships) {
          RelationshipFactory.deleteRelationship(rel);
        }
        relationships = RelationshipFactory.getRelationshipsByChild(structure);
        for (Relationship rel : relationships) {
          RelationshipFactory.deleteRelationship(rel);
        }

        PermissionAPI perAPI = APILocator.getPermissionAPI();
        perAPI.removePermissions(structure);

        StructureFactory.deleteStructure(structure);

        // Removing the structure from cache
        FieldsCache.removeFields(structure);
        StructureCache.removeStructure(structure);
        StructureServices.removeStructureFile(structure);

        SessionMessages.add(req, "message", "message.structure.deletestructure");
      } else {
        SessionMessages.add(req, "message", "message.structure.notdeletestructure");
      }
    } catch (Exception ex) {
      Logger.debug(EditStructureAction.class, ex.toString());
      throw ex;
    }
  }
  private void _saveStructure(ActionForm form, ActionRequest req, ActionResponse res) {
    try {
      boolean newStructure = false;
      StructureForm structureForm = (StructureForm) form;
      Structure structure = (Structure) req.getAttribute(WebKeys.Structure.STRUCTURE);

      User user = _getUser(req);
      HttpServletRequest httpReq = ((ActionRequestImpl) req).getHttpServletRequest();

      if (!UtilMethods.isSet(structureForm.getHost())
          && (!UtilMethods.isSet(structureForm.getFolder())
              || structureForm.getFolder().equals("SYSTEM_FOLDER"))) {
        throw new DotDataException(LanguageUtil.get(user, "Host-or-folder-is-required"));
      }

      // Checking permissions
      _checkWritePermissions(structure, user, httpReq);

      // Check if another structure with the same name exist
      String auxStructureName = structureForm.getName();
      auxStructureName = (auxStructureName != null ? auxStructureName.trim() : "");

      @SuppressWarnings("deprecation")
      Structure auxStructure = StructureCache.getStructureByType(auxStructureName);

      if (InodeUtils.isSet(auxStructure.getInode())
          && !auxStructure.getInode().equalsIgnoreCase(structure.getInode())) {
        throw new DotDataException(
            LanguageUtil.get(user, "There-is-another-structure-with-the-same-name"));
      }

      Arrays.sort(reservedStructureNames);
      if (!InodeUtils.isSet(structureForm.getInode())
          && (Arrays.binarySearch(reservedStructureNames, auxStructureName) >= 0)) {
        throw new DotDataException("Invalid Reserved Structure Name : " + auxStructureName);
      }

      // Validate if is a new structure and if the name hasn't change
      if (!InodeUtils.isSet(structure.getInode())) {
        newStructure = true;
      } else {
        String structureName = structure.getName();
        String structureFormName = structureForm.getName();
        if (UtilMethods.isSet(structureName)
            && UtilMethods.isSet(structureFormName)
            && !structureName.equals(structureFormName)
            && !structure.isFixed()) {

          StructureCache.removeStructure(structure);
        }
      }

      // If the structure is fixed the name cannot be changed
      if (structure.isFixed()) {
        structureForm.setName(structure.getName());
      }

      // if I'm editing a structure the structureType couldn't not be
      // change
      if (UtilMethods.isSet(structure.getInode()) && InodeUtils.isSet(structure.getInode())) {
        // reset the structure type to it's original value
        structureForm.setStructureType(structure.getStructureType());
      }
      if (UtilMethods.isSet(structure.getVelocityVarName())) {
        structureForm.setVelocityVarName(structure.getVelocityVarName());
      }
      if (UtilMethods.isSet(structureForm.getHost())) {
        if (!structureForm.getHost().equals(Host.SYSTEM_HOST)
            && hostAPI.findSystemHost().getIdentifier().equals(structureForm.getHost())) {
          structureForm.setHost(Host.SYSTEM_HOST);
        }
        structureForm.setFolder("SYSTEM_FOLDER");
      } else if (UtilMethods.isSet(structureForm.getFolder())) {
        structureForm.setHost(folderAPI.find(structureForm.getFolder(), user, false).getHostId());
      }

      if (UtilMethods.isSet(structureForm.getHost())
          && (!UtilMethods.isSet(structureForm.getFolder())
              || structureForm.getFolder().equals("SYSTEM_FOLDER"))) {
        Host host = hostAPI.find(structureForm.getHost(), user, false);
        if (host != null) {
          if (structure.getStructureType() == Structure.STRUCTURE_TYPE_FORM) {
            if (!perAPI.doesUserHavePermissions(
                host,
                "PARENT:"
                    + PermissionAPI.PERMISSION_CAN_ADD_CHILDREN
                    + ", STRUCTURES:"
                    + PermissionAPI.PERMISSION_PUBLISH,
                user)) {
              throw new DotDataException(
                  LanguageUtil.get(
                      user, "User-does-not-have-add-children-permission-on-host-folder"));
            }
          } else {
            if (!perAPI.doesUserHavePermission(
                host, PermissionAPI.PERMISSION_CAN_ADD_CHILDREN, user)) {
              throw new DotDataException(
                  LanguageUtil.get(
                      user, "User-does-not-have-add-children-permission-on-host-folder"));
            }
          }
        }
      }

      if (UtilMethods.isSet(structureForm.getFolder())
          && !structureForm.getFolder().equals("SYSTEM_FOLDER")) {
        Folder folder = folderAPI.find(structureForm.getFolder(), user, false);
        if (folder != null) {
          if (structure.getStructureType() == Structure.STRUCTURE_TYPE_FORM) {
            if (!perAPI.doesUserHavePermissions(
                folder,
                "PARENT:"
                    + PermissionAPI.PERMISSION_CAN_ADD_CHILDREN
                    + ", STRUCTURES:"
                    + PermissionAPI.PERMISSION_PUBLISH,
                user)) {
              throw new DotDataException(
                  LanguageUtil.get(
                      user, "User-does-not-have-add-children-permission-on-host-folder"));
            }
          } else {
            if (!perAPI.doesUserHavePermission(
                folder, PermissionAPI.PERMISSION_CAN_ADD_CHILDREN, user)) {
              throw new DotDataException(
                  LanguageUtil.get(
                      user, "User-does-not-have-add-children-permission-on-host-folder"));
            }
          }
        }
      }

      BeanUtils.copyProperties(structure, structureForm);

      // if htmlpage doesn't exist page id should be an identifier. Should
      // be refactored once we get identifierAPI/HTMLPage API done
      String pageDetail = structureForm.getDetailPage();

      if (newStructure) {
        String structureVelocityName =
            VelocityUtil.convertToVelocityVariable(structure.getName(), true);
        List<String> velocityvarnames = StructureFactory.getAllVelocityVariablesNames();
        int found = 0;
        if (VelocityUtil.isNotAllowedVelocityVariableName(structureVelocityName)) {
          found++;
        }

        for (String velvar : velocityvarnames) {
          if (velvar != null) {
            if (structureVelocityName.equalsIgnoreCase(velvar)) {
              found++;
            } else if (velvar.toLowerCase().contains(structureVelocityName.toLowerCase())) {
              String number = velvar.substring(structureVelocityName.length());
              if (RegEX.contains(number, "^[0-9]+$")) {
                found++;
              }
            }
          }
        }
        if (found > 0) {
          structureVelocityName = structureVelocityName + Integer.toString(found);
        }
        structure.setVelocityVarName(structureVelocityName);
      }

      if (UtilMethods.isSet(pageDetail)) {
        structure.setDetailPage(pageDetail);
      }

      // Saving interval review properties
      if (structureForm.isReviewContent()) {
        structure.setReviewInterval(
            structureForm.getReviewIntervalNum() + structureForm.getReviewIntervalSelect());
      } else {
        structure.setReviewInterval(null);
        structure.setReviewerRole(null);
      }

      // If there is no default structure this would be
      Structure defaultStructure = StructureFactory.getDefaultStructure();
      if (!InodeUtils.isSet(defaultStructure.getInode())) {
        structure.setDefaultStructure(true);
      }
      if (newStructure) {
        structure.setFixed(false);
        structure.setOwner(user.getUserId());
      }
      // validate iit is a form structure set it as system by default
      if (structureForm.getStructureType() == Structure.STRUCTURE_TYPE_FORM) {
        structure.setSystem(true);
      }
      StructureFactory.saveStructure(structure);
      structureForm.setUrlMapPattern(structure.getUrlMapPattern());

      WorkflowScheme scheme = APILocator.getWorkflowAPI().findSchemeForStruct(structure);

      String schemeId = req.getParameter("workflowScheme");

      if (scheme != null && UtilMethods.isSet(schemeId) && !schemeId.equals(scheme.getId())) {
        scheme = APILocator.getWorkflowAPI().findScheme(schemeId);
        APILocator.getWorkflowAPI().saveSchemeForStruct(structure, scheme);
      }

      // if the structure is a widget we need to add the base fields.
      if (newStructure && structureForm.getStructureType() == Structure.STRUCTURE_TYPE_WIDGET) {
        wAPI.createBaseWidgetFields(structure);
      }

      // if the structure is a form we need to add the base fields.
      if (newStructure && structureForm.getStructureType() == Structure.STRUCTURE_TYPE_FORM) {
        fAPI.createBaseFormFields(structure);
      }

      // if the structure is a form we need to add the base fields.
      if (newStructure && structureForm.getStructureType() == Structure.STRUCTURE_TYPE_FILEASSET) {
        APILocator.getFileAssetAPI().createBaseFileAssetFields(structure);
      }
      if (!newStructure) {
        perAPI.resetPermissionReferences(structure);
      }

      // Saving the structure in cache
      StructureCache.removeStructure(structure);
      StructureCache.addStructure(structure);
      StructureServices.removeStructureFile(structure);

      String message = "message.structure.savestructure";
      if (structure.getStructureType() == 3) {
        message = "message.form.saveform";
      }
      SessionMessages.add(req, "message", message);
      AdminLogger.log(
          EditStructureAction.class,
          "_saveStructure",
          "Structure saved : " + structure.getName(),
          user);
    } catch (Exception ex) {
      Logger.error(this.getClass(), ex.toString());
      String message = ex.toString();
      SessionMessages.add(req, "error", message);
    }
  }