public int getDone() {
   int done = 0;
   if (tController != null) {
     Collection<AnalysisThread> tCollection =
         (Collection<AnalysisThread>) tController.getThreads();
     for (AnalysisThread aThread : tCollection) {
       if (aThread.isDone()) {
         done++;
       }
     }
   }
   return done;
 }
  public List<String> getMessages() {
    List<String> messages = null;
    if (tController != null) {
      Collection<AnalysisThread> tCollection =
          (Collection<AnalysisThread>) tController.getThreads();
      for (AnalysisThread t : tCollection) {
        if (!t.isAlive()) {
          if (t.hasError()) {
            if (messages == null) {
              messages = new ArrayList<String>();
            }

            messages.add(t.getErrorMessage());
          }
        }
      }
    }
    return messages;
  }
  /**
   * Initialize the analysis thread group
   *
   * @param selectedNodes Selected documents to be analyzed
   * @param userId Logged user ID
   * @param selectedAlgorithms Selected algorithms
   * @return
   */
  public boolean performAnalysis(
      List<DocumentDragVO> selectedNodes, long userId, AlgorithmDTO[] selectedAlgorithms) {

    try {
      Connection dbUtility = ConnectionFactory.createConnection();

      Set<AnalysisThread> threadSet = new HashSet<AnalysisThread>();

      ThreadGroup analysisGroup = ThreadController.createSubGroup("AnalysisGroup");

      String[] args = {
        String.valueOf(ResourceUtility.getCurrentGroupId()),
        String.valueOf(ResourceUtility.getCurrentUserId()),
        String.valueOf(ResourceUtility.getCurrentCompanyId())
      };
      FileStorer fileStorer =
          FileStoreFactory.returnFileStore(ResourceUtility.getFileStorageType(), args);

      for (DocumentDragVO node : selectedNodes) {

        List<FileInfoDTO> files =
            dbUtility.getAllFilesByDocumentRecordId(node.getDocumentRecord().getDocumentRecordId());
        FSFile headerFile = fileStorer.getFile(files.get(0).getFileEntryId(), true);

        FileType originalFileType = node.getDocumentRecord().getOriginalFormat();
        long docId = node.getDocumentRecord().getDocumentRecordId();
        String timeseriesId = node.getDocumentRecord().getTimeSeriesId();
        String name = node.getDocumentRecord().getRecordName();
        String age = node.getDocumentRecord().getAge().toString();
        String sex = node.getDocumentRecord().getGender();
        String channels = String.valueOf(node.getDocumentRecord().getLeadCount());
        String scalingFactor = String.valueOf(node.getDocumentRecord().getAduGain());
        String samplesPerChannel = String.valueOf(node.getDocumentRecord().getSamplesPerChannel());
        String samplingRate = String.valueOf(node.getDocumentRecord().getSamplingRate());

        ThreadGroup fileGroup = new ThreadGroup(analysisGroup, docId + "Group");
        List<Long> analysisIds = new ArrayList<Long>();

        for (AlgorithmDTO algorithm : selectedAlgorithms) {

          Map<String, Object> parameterMap = new HashMap<String, Object>();

          parameterMap.put("userID", String.valueOf(userId));
          parameterMap.put("groupID", String.valueOf(ResourceUtility.getCurrentGroupId()));
          parameterMap.put("folderID", String.valueOf(headerFile.getParentId()));
          parameterMap.put("subjectID", node.getDocumentRecord().getSubjectId());
          parameterMap.put("durationSec", node.getDocumentRecord().getDurationSec());
          parameterMap.put("channels", channels);
          parameterMap.put("leadNames", node.getDocumentRecord().getLeadNames());
          parameterMap.put("scalingFactor", scalingFactor);
          parameterMap.put("samplesPerChannel", samplesPerChannel);
          parameterMap.put("samplingRate", samplingRate);
          parameterMap.put("timeseriesId", timeseriesId);

          LinkedHashMap<String, String> parameterlistMap = new LinkedHashMap<String, String>();
          if ((originalFileType.getLabel().equals("Schiller"))
              && (algorithm.getDisplayShortName().contentEquals("QRS-Score"))) {
            List<AnnotationDTO> magellanAnnot =
                getMagellanLeadAnnotationList(userId, docId, "Schiller Upload", "ECGT");
            List<AnnotationDTO> magellanRecAnnot =
                getMagellanRecordAnnotationList(userId, docId, "Schiller Upload", "ECGT");
            String qrsd = null, qrsax = null;

            if (magellanRecAnnot.get(0) != null) {
              qrsd = magellanRecAnnot.get(0).getValue();
            }
            if (magellanRecAnnot.get(1) != null) {
              qrsax = magellanRecAnnot.get(1).getValue();
            }
            parameterlistMap =
                buildQRS_ScoreParameterListMap(docId, name, age, sex, qrsd, qrsax, magellanAnnot);
          }

          parameterMap.put("parameterlist", parameterlistMap);
          parameterMap.put("method", algorithm.getServiceMethod());
          parameterMap.put("serviceName", algorithm.getServiceName());
          parameterMap.put("URL", algorithm.getAnalysisServiceURL());
          parameterMap.put("openTsdbHost", ResourceUtility.getOpenTsdbHost());
          parameterMap.put("openTsdbStrategy", ResourceUtility.getOpenTsdStrategy());

          AnalysisJobDTO analysisJobDTO =
              dbUtility.storeAnalysisJob(
                  node.getFileNode().getDocumentRecordId(),
                  0,
                  0,
                  algorithm.getAnalysisServiceURL(),
                  algorithm.getServiceName(),
                  algorithm.getServiceMethod(),
                  new Date(),
                  ResourceUtility.getCurrentUserId());

          String jobID = "job_" + analysisJobDTO.getAnalysisJobId();

          parameterMap.put("jobID", jobID);

          AnalysisThread t =
              new AnalysisThread(
                  parameterMap,
                  node.getDocumentRecord(),
                  ResourceUtility.getCurrentUserId(),
                  dbUtility,
                  fileGroup,
                  fileStorer,
                  algorithm.getResultType());

          threadSet.add(t);

          analysisIds.add(analysisJobDTO.getAnalysisJobId());
        }
        AnalysisStatusDTO dto =
            new AnalysisStatusDTO(
                node.getDocumentRecord().getDocumentRecordId(),
                node.getDocumentRecord().getRecordName(),
                analysisIds.size(),
                0,
                0);
        dto.setAnalysisIds(analysisIds);
        this.addToBackgroundQueue(dto);
      }

      tController = new ThreadController(threadSet);
      tController.start();

      return true;
    } catch (FSException e) {
      e.printStackTrace();
    } catch (DataStorageException e) {
      e.printStackTrace();
    }

    return false;
  }
 public int getTotal() {
   return tController.getThreadCount();
 }