/**
  * Changes the values of the ID attributes of a case with new ones. This method traverses the
  * CaseComponent tree of a case modifing the values of the ids attributes with new objects.
  *
  * @param _case to modify the ids
  * @param componentsKeys stores the new values of the IDs attributes
  * @throws jcolibri.exception.ExecutionException
  */
 public static void defineNewIdsMethod(CBRCase _case, HashMap componentsKeys)
     throws jcolibri.exception.ExecutionException {
   defineNewIds(_case.getDescription(), componentsKeys);
   defineNewIds(_case.getSolution(), componentsKeys);
   defineNewIds(_case.getJustificationOfSolution(), componentsKeys);
   defineNewIds(_case.getResult(), componentsKeys);
 }
  protected void save(Collection queries, String filename) {
    try {
      BufferedWriter br = null;
      br = new BufferedWriter(new FileWriter(filename));
      if (br == null) throw new Exception("Error opening file for writing: " + filename);

      for (Object o : queries) {
        CBRCase _case = (CBRCase) o;
        br.write(_case.getID().toString());
        br.newLine();
      }
      br.close();
    } catch (Exception e) {
      org.apache.commons.logging.LogFactory.getLog(this.getClass()).error(e);
    }
  }
  /**
   * Sets the cases that both solve q or contribute to its misclassification. In the case of ICF we
   * only record cases that solve q. According to the ICF definition, a case solves a query if it is
   * of the same class as the query and if there are no classes more similar to the query with a
   * different class.
   *
   * @param q the query
   * @param cases from which to find the cases which solve and classify the query. These include the
   *     query itself.
   * @param knnConfig the similarity configuration
   */
  public void setCasesThatSolveAndMisclassifyQ(
      CBRCase q, Collection cases, KNNClassificationConfig knnConfig) {
    solveQ = new LinkedList();
    misclassifyQ = null;

    knnConfig.setK(RetrievalResult.RETRIEVE_ALL);
    Collection orderedRetrievedCases = NNScoringMethod.evaluateSimilarity(cases, q, knnConfig);
    orderedRetrievedCases = SelectCases.selectTopKRR(orderedRetrievedCases, knnConfig.getK());

    ClassificationOracle oracle = new BasicClassificationOracle();
    boolean disagreeingCaseFound = false;
    Iterator iter = orderedRetrievedCases.iterator();
    while (!disagreeingCaseFound && iter.hasNext()) {
      CBRCase c = ((RetrievalResult) iter.next()).get_case();
      ClassificationSolution cSol = (ClassificationSolution) c.getSolution();
      if (oracle.isCorrectPrediction(cSol, q)) {
        solveQ.add(c);
      } else {
        disagreeingCaseFound = true;
      }
    }
  }
  protected void splitCaseBaseFromFile(
      Collection wholeCaseBase, List querySet, List casebaseSet, String filename) {
    querySet.clear();
    casebaseSet.clear();

    casebaseSet.addAll(wholeCaseBase);

    try {
      BufferedReader br = null;
      br = new BufferedReader(new FileReader(FileIO.findFile(filename).getFile()));
      if (br == null) throw new Exception("Error opening file: " + filename);

      String line = "";
      while ((line = br.readLine()) != null) {
        CBRCase c = null;
        int pos = 0;
        boolean found = false;
        for (Iterator iter = casebaseSet.iterator(); iter.hasNext() && (!found); ) {
          c = (CBRCase) iter.next();
          if (c.getID().toString().equals(line)) found = true;
          else pos++;
        }
        if (c == null) {
          org.apache.commons.logging.LogFactory.getLog(this.getClass())
              .error("Case " + line + " not found into case base");
          continue;
        }

        casebaseSet.remove(pos);
        querySet.add(c);
      }
      br.close();
    } catch (Exception e) {
      org.apache.commons.logging.LogFactory.getLog(this.getClass()).error(e);
    }
  }