/**
   * Queries the archive for DICOM objects matching Attribute Keys defined in the loacal field
   * "keys". This field is set by the constructor out of the configuration parameters or by the
   * methods setQueryKeys(Configuration) and setQueryKeys(Dataset). See PS 3.4 - Annex C
   * QUERY/RETRIEVE SERVICE CLASS.
   *
   * <p>The method returns, when the result is received from the communication partner.
   *
   * @return the result of the cFIND as a Vector of Dataset objects each specifying one matching
   *     DICOM object. If no matching objects are found an empty Vector is returned.
   * @throws ConnectException
   * @throws IOException
   */
  public Vector cFIND() throws ConnectException, IOException, InterruptedException {

    List dimseList;
    Vector datasetVector;

    // An association must be active
    if (aassoc == null) {
      throw new ConnectException("No Association established");
    }

    // Test, if Presentation Context for C-FIND is supported
    // API doc: Association.getAcceptedPresContext(String asuid, String tsuid)
    //        UIDs.StudyRootQueryRetrieveInformationModelGET
    if ((pc =
                aassoc
                    .getAssociation()
                    .getAcceptedPresContext(
                        UIDs.StudyRootQueryRetrieveInformationModelFIND,
                        UIDs.ExplicitVRLittleEndian))
            == null
        && (pc =
                aassoc
                    .getAssociation()
                    .getAcceptedPresContext(
                        UIDs.StudyRootQueryRetrieveInformationModelFIND,
                        UIDs.ImplicitVRLittleEndian))
            == null) {
      throw new ConnectException(
          "Association does not support presentation context for StudyRootQueryRetrieveInformationModelFIND SOP.");
    }

    // New Cammand Set, see: DICOM Part 7: Message Exchange, 6.3.1 Command Set Structure
    Command rqCmd = dof.newCommand();
    // API doc: Command.initCFindRQ(int msgID, String sopClassUID, int priority)
    rqCmd.initCFindRQ(assoc.nextMsgID(), UIDs.StudyRootQueryRetrieveInformationModelFIND, priority);

    // API doc: AssociationFactorynewDimse(int pcid, Command cmd, Dataset ds)
    // DIMSE (DICOM Message Service Element) ist ein Nachrichtendienst in DICOM
    Dimse findRq = aFact.newDimse(pc.pcid(), rqCmd, keys);

    if (DEBUG) {
      StringWriter w = new StringWriter();
      w.write("C-FIND RQ Identifier:\n");
      keys.dumpDataset(w, null);
      log.debug(w.toString());
    }

    // Invoke active association with find request Dimse
    FutureRSP future = aassoc.invoke(findRq);
    // Response to the C-FIND request.
    // The result cannot be accessed until it has been set.
    Dimse findRsp = future.get();

    // Get the list of found objects
    dimseList = future.listPending();

    // >>>> Extract Dataset from Dimse

    datasetVector = new Vector();

    // If no List of DIMSE objects was generated or it is empty return an empty Vector
    if (dimseList == null || dimseList.isEmpty()) {
      return datasetVector;
    }

    // Process all elements
    for (int i = 0; i < dimseList.size(); i++) {
      datasetVector.addElement(((Dimse) dimseList.get(i)).getDataset());
    }

    return datasetVector;
  }
  public Vector cGET(Dataset ds) throws ConnectException, IOException, InterruptedException {
    PresContext pc;
    List dimseList;
    Vector datasetVector;

    // An association must be active
    if (aassoc == null) {
      throw new ConnectException("No Association established");
    }

    // Test, if Presentation Context for C-MOVE is supported
    // API doc: Association.getAcceptedPresContext(String asuid, String tsuid)
    if ((pc =
                aassoc
                    .getAssociation()
                    .getAcceptedPresContext(
                        UIDs.StudyRootQueryRetrieveInformationModelGET,
                        UIDs.ExplicitVRLittleEndian))
            == null
        && (pc =
                aassoc
                    .getAssociation()
                    .getAcceptedPresContext(
                        UIDs.StudyRootQueryRetrieveInformationModelGET,
                        UIDs.ImplicitVRLittleEndian))
            == null) {
      throw new ConnectException(
          "Association does not support presentation context for StudyRootQueryRetrieveInformationModelMOVE SOP.");
    }

    // Get the Study Instance UID of the study to mode
    String suid = ds.getString(Tags.SOPInstanceUID);

    // Prepare info for logging
    String patName = ds.getString(Tags.PatientName);
    String patID = ds.getString(Tags.PatientID);
    String studyDate = ds.getString(Tags.StudyDate);
    String prompt =
        "Study[" + suid + "] from " + studyDate + " for Patient[" + patID + "]: " + patName;

    // log.info("Moving: " + prompt);

    // New Cammand Set, see: DICOM Part 7: Message Exchange, 6.3.1 Command Set Structure
    Command rqCmd = dof.newCommand();
    // API doc: Command.initCMoveRQ(int msgID, String sopClassUID, int priority, String moveDest)
    rqCmd.initCGetRSP(assoc.nextMsgID(), UIDs.StudyRootQueryRetrieveInformationModelGET, priority);
    Dataset rqDs = dof.newDataset();
    rqDs.putCS(Tags.QueryRetrieveLevel, getQueryRetrieveLevel(STUDY_LEVEL));
    // Only Unique Key allowed in C-MOVE. PS 3.4 -C.2.2.1 Attribute Types
    rqDs.putUI(Tags.SOPInstanceUID, suid);
    // API doc: AssociationFactorynewDimse(int pcid, Command cmd, Dataset ds)
    // DIMSE (DICOM Message Service Element) ist ein Nachrichtendienst in DICOM
    Dimse moveRq = aFact.newDimse(pc.pcid(), rqCmd, rqDs);

    // Invoke active association with move request Dimse
    FutureRSP future = aassoc.invoke(moveRq);
    // Response to the C-MOVE request.
    // The result cannot be accessed until it has been set.
    Dimse moveRsp = future.get();
    Command rspCmd = moveRsp.getCommand();

    if (DEBUG) {
      StringWriter w = new StringWriter();
      w.write("C-FIND RQ Identifier:\n");
      keys.dumpDataset(w, null);
      log.debug(w.toString());
    }

    // Invoke active association with find request Dimse

    // Response to the C-FIND request.
    // The result cannot be accessed until it has been set.

    // Get the list of found objects
    dimseList = future.listPending();

    // >>>> Extract Dataset from Dimse

    datasetVector = new Vector();

    // If no List of DIMSE objects was generated or it is empty return an empty Vector
    if (dimseList == null || dimseList.isEmpty()) {
      return datasetVector;
    }

    // Process all elements
    for (int i = 0; i < dimseList.size(); i++) {
      datasetVector.addElement(((Dimse) dimseList.get(i)).getDataset());
      if (((Dimse) dimseList.get(i)).getDataset() == null)
        System.out.println("              Dataset created succesffullyu          ");
    }

    // PS 3.7 - 9.3.4 C-MOVE PROTOCOL, 9.3.4.2 C-MOVE-RSP
    int status = rspCmd.getStatus();
    switch (status) {
      case 0x0000:
        // log.info("Moved: " + prompt);
        break;
      case 0xB000:
        log.error("One or more failures during move of " + prompt);
        break;
      default:
        log.error("Failed to move " + prompt + "\n\terror tstatus: " + Integer.toHexString(status));
        break;
    }
    System.out.println("The move sise is : " + datasetVector.size());
    return datasetVector;
  }