Package com.pixelmed.apps

## Class StudyReceiver

- java.lang.Object
- - com.pixelmed.apps.StudyReceiver

-     public class StudyReceiver
      extends java.lang.Object

  A class to wait for incoming composite instance storage operations and process when study is complete based on time since last instance received.

  External (unsecure) SQL access to the database is possible if the Application.DatabaseServerName property is specified; further details are described in `com.pixelmed.database.DatabaseInformationModel`; for example:

      % java -cp lib/additional/hsqldb.jar org.hsqldb.util.DatabaseManagerSwing --url "jdbc:hsqldb:hsql://localhost/testserverdb"

  For how to configure the necessary properties file, see:

  See Also:
    `NetworkApplicationProperties`, `DatabaseApplicationProperties`

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Class | Description
    --- | --- | ---
    `protected class` | `StudyReceiver.OurPatientStudySeriesInstanceModel` |
    `protected static class` | `StudyReceiver.OurReadTerminationStrategy` |
    `protected class` | `StudyReceiver.OurReceivedObjectHandler` |
    `protected class` | `StudyReceiver.ReceivedFileProcessor` |
    `protected class` | `StudyReceiver.WatchDatabaseAndProcessCompleteStudies` |

  - ### Field Summary

    Fields
    Modifier and Type | Field | Description
    --- | --- | ---
    `protected java.lang.String` | `buildDate` |
    `protected java.io.File` | `completedStudiesFolder` |
    `protected DatabaseInformationModel` | `databaseInformationModel` |
    `protected java.lang.String` | `defaultCompletedStudiesFolderName` |
    `protected java.lang.String` | `defaultIntervalAfterLastInstanceReceivedToWaitBeforeProcessingStudy` |
    `protected static java.lang.String` | `defaultPropertiesFileName` |
    `protected java.lang.String` | `defaultSleepTimeBetweenPassesToProcessReceivedFiles` |
    `protected java.lang.String` | `instanceHasBeenProcessedColumnName` |
    `protected java.lang.String` | `instanceLocalFileNameColumnName` |
    `protected java.lang.String` | `instanceLocalFileReferenceTypeColumnName` |
    `protected java.lang.String` | `instanceLocalPrimaryKeyColumnName` |
    `protected static int` | `intervalAfterLastInstanceReceivedToWaitBeforeProcessingStudy` |
    `protected NetworkApplicationInformationFederated` | `networkApplicationInformation` |
    `protected NetworkApplicationProperties` | `networkApplicationProperties` |
    `protected java.lang.String` | `ourCalledAETitle` |
    `protected java.util.Properties` | `properties` |
    `protected static java.lang.String` | `propertyName_CompletedStudiesFolderName` |
    `protected static java.lang.String` | `propertyName_IntervalAfterLastInstanceReceivedToWaitBeforeProcessingStudy` |
    `protected static java.lang.String` | `propertyName_SleepTimeBetweenPassesToProcessReceivedFiles` |
    `protected java.io.File` | `savedImagesFolder` |
    `protected java.lang.String` | `seriesLocalPrimaryKeyColumnName` |
    `protected static int` | `sleepTimeBetweenPassesToProcessReceivedFiles` |
    `protected java.lang.String` | `sopClassUIDColumnName` |
    `protected StoredFilePathStrategy` | `storedFilePathStrategy` |
    `protected java.lang.String` | `studyHasBeenProcessedColumnName` |
    `protected java.lang.String` | `studyInstanceUIDColumnName` |
    `protected java.lang.String` | `studyMostRecentInsertionTimeColumnName` |
    `protected static AttributeList.ReadTerminationStrategy` | `terminateAfterRelationshipGroup` |

  - ### Constructor Summary

    Constructors
    Constructor | Description
    --- | ---
    `StudyReceiver​(java.lang.String propertiesFileName)` | Wait for incoming composite instance storage operations and process when study is complete based on time since last instance received.

  - ### Method Summary

    All Methods Static Methods Instance Methods Concrete Methods
    Modifier and Type | Method | Description
    --- | --- | ---
    `void` | `activateStorageSCP()` | Start or restart DICOM storage listener.
    `protected void` | `doSomethingWithProcessedDicomFile​(java.lang.String processedFileName)` | Do something with the processed DICOM file.
    `protected void` | `doSomethingWithReceivedDicomFile​(java.lang.String receivedFileName, java.lang.String sourceApplicationEntityTitle, java.lang.String transferSyntaxUID, java.lang.String sopClassUID)` | Do something with the received DICOM file.
    `protected java.lang.String` | `getBuildDate()` | Get the date the package was built.
    `protected java.io.File` | `getCompletedStudiesFolderNameCreatingItIfNecessary​(java.lang.String completedStudiesFolderName)` | Return the folder, creating it if necessary.
    `protected void` | `loadProperties​(java.lang.String propertiesFileName)` | Load properties.
    `static void` | `main​(java.lang.String[] arg)` | Wait for incoming composite instance storage operations and process when study is complete based on time since last instance received.
    `protected boolean` | `processStudy​(java.lang.String studyLocalPrimaryKeyValue)` |
    `protected boolean` | `processStudyIfComplete​(java.lang.String studyLocalPrimaryKeyValue)` |
    `protected java.lang.String` | `renameFileWithHierarchicalPathFromAttributes​(java.io.File file, AttributeList list, java.lang.String hierarchicalFolderName, java.lang.String duplicatesFolderNamePrefix)` | Rename a DICOM file into a folder hierarchy based on its attributes that are already available.
    `void` | `shutdownStorageSCP()` | Shutdown DICOM storage listener.
    `protected void` | `updateStudyMostRecentInsertionTime​(java.lang.String studyInstanceUID, long insertionTime)` |

    - ### Methods inherited from class java.lang.Object

      `clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Field Detail

    - #### defaultPropertiesFileName

          protected static java.lang.String defaultPropertiesFileName

    - #### propertyName_CompletedStudiesFolderName

          protected static java.lang.String propertyName_CompletedStudiesFolderName

    - #### propertyName_SleepTimeBetweenPassesToProcessReceivedFiles

          protected static java.lang.String propertyName_SleepTimeBetweenPassesToProcessReceivedFiles

    - #### propertyName_IntervalAfterLastInstanceReceivedToWaitBeforeProcessingStudy

          protected static java.lang.String propertyName_IntervalAfterLastInstanceReceivedToWaitBeforeProcessingStudy

    - #### defaultCompletedStudiesFolderName

          protected java.lang.String defaultCompletedStudiesFolderName

    - #### defaultSleepTimeBetweenPassesToProcessReceivedFiles

          protected java.lang.String defaultSleepTimeBetweenPassesToProcessReceivedFiles

    - #### defaultIntervalAfterLastInstanceReceivedToWaitBeforeProcessingStudy

          protected java.lang.String defaultIntervalAfterLastInstanceReceivedToWaitBeforeProcessingStudy

    - #### sleepTimeBetweenPassesToProcessReceivedFiles

          protected static int sleepTimeBetweenPassesToProcessReceivedFiles

    - #### intervalAfterLastInstanceReceivedToWaitBeforeProcessingStudy

          protected static int intervalAfterLastInstanceReceivedToWaitBeforeProcessingStudy

    - #### properties

          protected java.util.Properties properties

    - #### networkApplicationProperties

          protected NetworkApplicationProperties networkApplicationProperties

    - #### networkApplicationInformation

          protected NetworkApplicationInformationFederated networkApplicationInformation

    - #### ourCalledAETitle

          protected java.lang.String ourCalledAETitle

    - #### databaseInformationModel

          protected DatabaseInformationModel databaseInformationModel

    - #### buildDate

          protected java.lang.String buildDate

    - #### completedStudiesFolder

          protected java.io.File completedStudiesFolder

    - #### savedImagesFolder

          protected java.io.File savedImagesFolder

    - #### storedFilePathStrategy

          protected StoredFilePathStrategy storedFilePathStrategy

    - #### studyHasBeenProcessedColumnName

          protected java.lang.String studyHasBeenProcessedColumnName

    - #### studyMostRecentInsertionTimeColumnName

          protected java.lang.String studyMostRecentInsertionTimeColumnName

    - #### instanceHasBeenProcessedColumnName

          protected java.lang.String instanceHasBeenProcessedColumnName

    - #### studyInstanceUIDColumnName

          protected java.lang.String studyInstanceUIDColumnName

    - #### sopClassUIDColumnName

          protected java.lang.String sopClassUIDColumnName

    - #### instanceLocalFileNameColumnName

          protected java.lang.String instanceLocalFileNameColumnName

    - #### instanceLocalFileReferenceTypeColumnName

          protected java.lang.String instanceLocalFileReferenceTypeColumnName

    - #### instanceLocalPrimaryKeyColumnName

          protected java.lang.String instanceLocalPrimaryKeyColumnName

    - #### seriesLocalPrimaryKeyColumnName

          protected java.lang.String seriesLocalPrimaryKeyColumnName

    - #### terminateAfterRelationshipGroup

          protected static final AttributeList.ReadTerminationStrategy terminateAfterRelationshipGroup

  - ### Constructor Detail

    - #### StudyReceiver

          public StudyReceiver​(java.lang.String propertiesFileName)
                        throws DicomException,
                               DicomNetworkException,
                               java.io.IOException,
                               java.lang.InterruptedException

      Wait for incoming composite instance storage operations and process when study is complete based on time since last instance received.

      Parameters:
        `propertiesFileName` -
      Throws:
        `DicomException`
        `DicomNetworkException`
        `java.io.IOException`
        `java.lang.InterruptedException`

  - ### Method Detail

    - #### getBuildDate

          protected java.lang.String getBuildDate()

      Get the date the package was built.

      Returns:
        the build date

    - #### loadProperties

          protected void loadProperties​(java.lang.String propertiesFileName)
                                 throws java.io.IOException

      Load properties.

      Throws:
        `java.io.IOException` - thrown if properties file is missing

    - #### renameFileWithHierarchicalPathFromAttributes

          protected java.lang.String renameFileWithHierarchicalPathFromAttributes​(java.io.File file,
                                                                                  AttributeList list,
                                                                                  java.lang.String hierarchicalFolderName,
                                                                                  java.lang.String duplicatesFolderNamePrefix)
                                                                           throws java.io.IOException,
                                                                                  DicomException,
                                                                                  java.security.NoSuchAlgorithmException

      Rename a DICOM file into a folder hierarchy based on its attributes that are already available.

      Called by `processStudy()` for each file that has been received for a completed study.

      Override this method in a sub-class if you want to override the default folder structure used to store the received files, otherwise creates a folder structure using `com.pixelmed.dicom.MoveDicomFilesIntoHierarchy.renameFileWithHierarchicalPathFromAttributes()`.

      Parameters:
        `file` - the DICOM file
        `list` - the attributes of the file (already read in)
        `hierarchicalFolderName` - where to store the renamed file
        `duplicatesFolderNamePrefix` - where to store the renamed file if it is a non-identical duplicate of the existing file
      Returns:
        the path to the new file if successful, null if not
      Throws:
        `java.io.IOException` - if an error occurs renaming the files
        `DicomException` - if there is an error parsing the attribute list
        `java.security.NoSuchAlgorithmException` - if there is an error checking duplicate files contain identical content caused by absence of a hash algorithm

    - #### doSomethingWithProcessedDicomFile

          protected void doSomethingWithProcessedDicomFile​(java.lang.String processedFileName)

      Do something with the processed DICOM file.

      This method may be implemented in a sub-class to do something useful even if it is only logging to the user interface.

      The default method does nothing.

      This method is called on the WatchDatabaseAndProcessCompleteStudies thread.

      This method does not define any exceptions and hence must handle any errors locally.

      Parameters:
        `processedFileName` - the path name to a DICOM file

    - #### processStudy

          protected boolean processStudy​(java.lang.String studyLocalPrimaryKeyValue)
                                  throws DicomException,
                                         java.io.IOException,
                                         java.lang.Exception

      Throws:
        `DicomException`
        `java.io.IOException`
        `java.lang.Exception`

    - #### processStudyIfComplete

          protected boolean processStudyIfComplete​(java.lang.String studyLocalPrimaryKeyValue)
                                            throws DicomException,
                                                   java.io.IOException,
                                                   java.lang.Exception

      Throws:
        `DicomException`
        `java.io.IOException`
        `java.lang.Exception`

    - #### updateStudyMostRecentInsertionTime

          protected void updateStudyMostRecentInsertionTime​(java.lang.String studyInstanceUID,
                                                            long insertionTime)
                                                     throws DicomException

      Throws:
        `DicomException`

    - #### doSomethingWithReceivedDicomFile

          protected void doSomethingWithReceivedDicomFile​(java.lang.String receivedFileName,
                                                          java.lang.String sourceApplicationEntityTitle,
                                                          java.lang.String transferSyntaxUID,
                                                          java.lang.String sopClassUID)

      Do something with the received DICOM file.

      This method may be implemented in a sub-class to do something useful even if it is only logging to the user interface.

      The default method does nothing.

      This method is called on the ReceivedFileProcessor thread.

      This method does not define any exceptions and hence must handle any errors locally.

      Parameters:
        `receivedFileName` - the path name to a DICOM file
        `sourceApplicationEntityTitle` - the Application Entity from which the file was received
        `transferSyntaxUID` - the Transfer Syntax of the Data Set in the DICOM file
        `sopClassUID` - the SOP Class of the Data Set in the DICOM file

    - #### getCompletedStudiesFolderNameCreatingItIfNecessary

          protected java.io.File getCompletedStudiesFolderNameCreatingItIfNecessary​(java.lang.String completedStudiesFolderName)
                                                                             throws java.io.IOException

      Return the folder, creating it if necessary.

      If not an absolute path, will be sought or created relative to the current user's home directory.

      Returns:
        the folder
      Throws:
        `java.io.IOException`

    - #### activateStorageSCP

          public void activateStorageSCP()
                                  throws DicomException,
                                         java.io.IOException

      Start or restart DICOM storage listener.

      Shuts down existing listener, if any, so may be used to restart after configuration change.

      Throws:
        `DicomException`
        `java.io.IOException`

    - #### shutdownStorageSCP

          public void shutdownStorageSCP()

      Shutdown DICOM storage listener.

    - #### main

          public static void main​(java.lang.String[] arg)

      Wait for incoming composite instance storage operations and process when study is complete based on time since last instance received.

      Parameters:
        `arg` - none