public String gridElementToFormattedString(GridElement ge) {
   String name =
       ge.getClass().getSimpleName()
           + " "
           + ge.getLabel()
           + " - <i>v"
           + ge.getVersion()
           + "</i><br>";
   String desc = "";
   String references = "";
   Field[] fields = ge.getClass().getDeclaredFields();
   for (int j = 0; j < fields.length; j++) {
     Field tempField = fields[j];
     tempField.setAccessible(true);
     try {
       Object fieldValue = tempField.get(ge);
       if (fieldValue instanceof GridElement) {
         GridElement currentGE = (GridElement) fieldValue;
         if (references.length() == 0) {
           references =
               references + "riferimenti: " + currentGE.getLabel() + " v" + currentGE.getVersion();
         } else {
           references = references + ", " + currentGE.getLabel() + " v" + currentGE.getVersion();
         }
       } else if (fieldValue instanceof List) {
         List myList = (List) fieldValue;
         if (myList.size() > 0) {
           Object first = myList.get(0);
           if (first instanceof GridElement) {
             GridElement currentGE = (GridElement) first;
             if (references.length() == 0) {
               references =
                   references
                       + "riferimenti: "
                       + currentGE.getLabel()
                       + " v"
                       + currentGE.getVersion();
             } else {
               references =
                   references + ", " + currentGE.getLabel() + " v" + currentGE.getVersion();
             }
           }
         }
       } else {
         // desc=desc+"<div style='float:left;min-width: 200px;'>"+tempField.getName()+":
         // "+fieldValueStr+"</div>";
         if (fieldValue != null) {
           String fieldValueStr = (String) fieldValue.toString();
           String txt = tempField.getName() + ": </i> " + fieldValueStr;
           int maxLength = 60;
           if (txt.length() > maxLength) txt = txt.substring(0, maxLength) + "...";
           desc = desc + "<div class='txtElement'><i>" + txt + "</div>";
         }
       }
     } catch (IllegalArgumentException e) {
       e.printStackTrace();
     } catch (IllegalAccessException e) {
       e.printStackTrace();
     }
   }
   return name + "\n\t" + desc + "\n\t" + references;
 }
  @RequestMapping(value = "/MGListUpdate", method = RequestMethod.POST)
  public @ResponseBody String updateMainGoalList(@RequestBody String jsonData) {
    System.out.println(jsonData);
    // Array format: [projId, gridSolved, {MaingoalList}]
    JSONArray jsonArray = new JSONArray(jsonData);
    int prjId = 0;
    int gridToSolveId = 0;
    List<Goal> mainGoalList = new ArrayList<Goal>();
    for (int i = 0; i < jsonArray.length(); i++) {
      if (i == 0) prjId = Integer.parseInt(jsonArray.getString(i));
      else if (i == 1) {
        gridToSolveId = Integer.parseInt(jsonArray.getString(i));
      } else {
        Goal current =
            (Goal) this.gridElementService.getLatestWorking(jsonArray.getString(i), "Goal");
        if (current != null && !mainGoalList.contains(current)) {
          mainGoalList.add(current);
        } else if (current == null) {
          JSONObject jsonObject = new JSONObject();
          jsonObject.put("type", "error");
          jsonObject.put("msg", "Cannot get working element with label: " + jsonArray.getString(i));
          // System.out.println("error, cannot get working element with label: "+
          // jsonArray.getString(i));
          return jsonObject.toString();
        }
      }
    }
    Grid workingGrid = this.gridService.getLatestWorkingGrid(prjId);
    Grid gridToSolve = this.gridService.getGridById(gridToSolveId);
    if (workingGrid == null) {
      JSONObject jsonObject = new JSONObject();
      jsonObject.put("type", "error");
      jsonObject.put("msg", "Cannot get latest working grid for project: " + prjId);
      // System.out.println("error, cannot get latest working grid for project: "+ prjId);
      return jsonObject.toString();
    } else if (gridToSolve == null) {
      JSONObject jsonObject = new JSONObject();
      jsonObject.put("type", "error");
      jsonObject.put("msg", "error, cannot get grid with id: " + gridToSolveId);
      System.out.println("error, cannot get grid with id: " + gridToSolveId);
      return jsonObject.toString();
    } else if ((!gridToSolve.isMainGoalsChanged())) {
      JSONObject jsonObject = new JSONObject();
      jsonObject.put("type", "error");
      jsonObject.put("msg", "grid with id: " + gridToSolveId + " has been already solved");
      System.out.println("error, cannot get grid with id: " + gridToSolveId);
      return jsonObject.toString();
    } else if (mainGoalList.size() == 0) {
      JSONObject jsonObject = new JSONObject();
      jsonObject.put("type", "error");
      jsonObject.put("msg", "Main goal list can't be empty");
      System.out.println("error, Main goal list can't be empty");
      return jsonObject.toString();
    } else {
      boolean solvable = true;
      for (Goal ge : mainGoalList) {
        if (solvable) {
          List<GridElement> pending =
              this.gridElementService.getElementByLabelAndState(
                  ge.getLabel(), "Goal", GridElement.State.MAJOR_CONFLICTING);
          pending.addAll(
              this.gridElementService.getElementByLabelAndState(
                  ge.getLabel(), "Goal", GridElement.State.MAJOR_UPDATING));
          pending.addAll(
              this.gridElementService.getElementByLabelAndState(
                  ge.getLabel(), "Goal", GridElement.State.MINOR_CONFLICTING));
          if (pending.size() > 0) {
            solvable = false;
          }
          if (solvable) {
            if (this.gridModificationService.isEmbeddedPending(ge)) solvable = false;
          }
        }
      }
      if (solvable) {
        for (GridElement ge : mainGoalList) {
          System.out.println(ge.getLabel() + "-" + ge.getVersion() + "-" + ge.getState());
        }
        Grid newGrid = workingGrid.clone();
        newGrid.setVersion(this.gridService.getLatestGrid(prjId).getVersion() + 1);
        newGrid.setMainGoals(mainGoalList);
        newGrid = this.gridModificationService.refreshLinks(newGrid);
        this.gridService.addGrid(newGrid);
        gridToSolve.setMainGoalsChanged(false);
        this.gridService.updateGrid(gridToSolve);
        this.gridModificationService.sendJSONToPhases(gridToSolve);
        this.gridModificationService.sendNewGridVersionNotification(newGrid);

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("type", "success");
        jsonObject.put("msg", "Main goal list updated");
        return jsonObject.toString();

      } else {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("type", "error");
        jsonObject.put("msg", "Other pending elements to solve before");
        return jsonObject.toString();
      }
    }
  }
 private String updateChart(List<Object> stack) {
   String chart = "";
   for (int i = 0; i < stack.size(); i++) {
     String image = "";
     String name = "";
     String desc = "";
     List<Object> newStack = new ArrayList<Object>();
     GridElement ge = (GridElement) stack.get(i);
     name =
         stack.get(i).getClass().getSimpleName()
             + " "
             + ge.getLabel()
             + " - <i>"
             + Utils.dateStringFromTimestamp(ge.getTimestamp())
             + "</i>";
     desc = "<div class='txtElement'><i>" + ge.getState().name() + "</i></div>";
     // TODO this part is not the same in utils?? (obtain HTML)
     Field[] fields = ge.getClass().getDeclaredFields();
     for (int j = 0; j < fields.length; j++) {
       Field tempField = fields[j];
       tempField.setAccessible(true);
       try {
         Object fieldValue = tempField.get(ge);
         if (fieldValue instanceof GridElement) {
           newStack.add(fieldValue);
         } else if (fieldValue instanceof List) {
           List myList = (List) fieldValue;
           if (myList.size() > 0) {
             Object first = myList.get(0);
             if (first instanceof GridElement) {
               newStack.addAll(myList);
             }
           }
         } else {
           // desc=desc+"<div style='float:left;min-width: 200px;'>"+tempField.getName()+":
           // "+fieldValueStr+"</div>";
           if (fieldValue != null) {
             if (!tempField.getName().equals("logger")) {
               String fieldValueStr = (String) fieldValue.toString();
               String txt = tempField.getName() + ": </i> " + fieldValueStr;
               int maxLength = 60;
               if (txt.length() > maxLength) txt = txt.substring(0, maxLength) + "...";
               desc = desc + "<div class='txtElement'><i>" + txt + "</div>";
             }
           }
         }
       } catch (IllegalArgumentException e) {
         e.printStackTrace();
       } catch (IllegalAccessException e) {
         e.printStackTrace();
       }
     }
     String geType = "";
     if (ge.getClass().getSimpleName().equals("Goal")
         || ge.getClass().getSimpleName().equals("Strategy")) {
       geType = "HTMLclass: 'gqmplusstrategy',";
     } else {
       geType = "HTMLclass: 'gqmgraph',";
     }
     chart =
         chart
             + "\n{"
             + geType
             + " innerHTML:\"<div style=\'background-color: red;\'><div class=\'nodeTxt\'><div class='txtElementTitle'><div class='nodeImg' ><img src='/ISSSR/resources/images/ImgGVS/"
             + ge.getClass().getSimpleName()
             + ".png' /></div><a style='z-index: 10;position:relative; color:black;' href='/ISSSR/element/"
             + ge.getClass().getSimpleName()
             + "/"
             + ge.getIdElement()
             + "'>"
             + name
             + "</a></div>"
             + desc
             + "</div></div>\", ";
     // chart=chart+"{text: { name: \""+name+"\", desc: \""+desc+"\"
     // },innerHTML:\"<div><h1>test</h1></div>\", collapsed: true";
     if (newStack.size() > 0) {
       chart = chart + " collapsed: true ,children: [";
       chart = chart + updateChart(newStack);
       chart = chart + "]";
     } else chart = chart + " collapsed: false";
     chart = chart + "}";
     if (i < stack.size() - 1) chart = chart + ",";
   }
   return chart;
 }
  @RequestMapping(value = "/solveUpdate", method = RequestMethod.POST)
  public @ResponseBody String solveUpdate(@RequestBody String jsonData) {
    JSONObject obj = new JSONObject(jsonData);
    String type = obj.getString("type");
    int id = obj.getInt("id");
    System.out.println("-------------->>>>" + id);
    int nconflict = obj.getInt("nconflict");
    GridElement ge = null;
    try {
      ge =
          this.gridElementService
              .getElementById(id, type)
              .clone(); // (GridElement)gson.fromJson(jsonGE, Class.forName(type));
      List<GridElement> pending =
          this.gridElementService.getElementByLabelAndState(
              ge.getLabel(), type, GridElement.State.MAJOR_CONFLICTING);
      pending.addAll(
          this.gridElementService.getElementByLabelAndState(
              ge.getLabel(), type, GridElement.State.MAJOR_UPDATING));
      pending.addAll(
          this.gridElementService.getElementByLabelAndState(
              ge.getLabel(), type, GridElement.State.MINOR_CONFLICTING));
      // System.out.println("pendingsize:"+pending.size());
      if (pending.size() == nconflict) {
        // if ge is not linked to pending objects
        boolean withPending = false;

        for (GridElement currentGE : pending) {
          if ((!withPending) && (this.gridModificationService.isEmbeddedPending(currentGE))) {
            withPending = true;
          }
        }

        // apply modifications to grid element
        if (!withPending) {
          this.gridModificationService.applyAModificationToASingleElement(ge);
        } else {
          JSONObject jsonObject = new JSONObject();
          jsonObject.put("type", "error");
          jsonObject.put("msg", "Cannot update: linked to pending elements");
          return jsonObject.toString();
        }

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("type", "success");
        jsonObject.put("msg", "The conflict has been solved");
        return jsonObject.toString();

      } else if (pending.size() > nconflict) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("type", "error");
        jsonObject.put("msg", "Other incoming updates to solve");
        return jsonObject.toString();

      } else if (pending.size() == 0) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("type", "error");
        jsonObject.put("msg", "No pending elements to solve");
        return jsonObject.toString();

      } else {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("type", "error");
        jsonObject.put("msg", "System Error, please contact the System Administrator");
        return jsonObject.toString();
      }

    } catch (Exception e) {
      JSONObject jsonObject = new JSONObject();
      jsonObject.put("type", "error");
      jsonObject.put("msg", "Generic Exception, please contact the System Administrator");
      e.printStackTrace();
      return jsonObject.toString();
    }
  }