The MIRC Module
The MIRC module (MIRC.jar) contains the code of the CTP plugin that implements TFS, the RSNA Teaching File System. This article describes the theory of operation of the packages and files contained in the MIRC module. The intended audience for this article is software engineers extending or maintaining any of that software. Prerequisites for understanding this article are The Util Module and The CTP Module.
See Setting Up a MIRC Development Environment for information on obtaining and building the MIRC module. It will be helpful to get the source code and build it so you can reference the Javadocs as you go along.
1 Overview
The MIRC module contains many packages. In general, major system functions (as well as some minor ones) are encapsulated in their own packages, but because many functions interact, this principle is not universally maintained. Most system functions have classes and files that are contained in the jar file. Often, the files are XSL programs used for the generation of web pages or Javascript and CSS files referenced by the web pages. These files are served directly from the jar file without having to be installed on the disk. See The Util Module for a description of how the server serves files from the classpath.
2 The TFS-installer
The TFS-installer uses the same installer program as CTP. It includes a full installation of CTP, but it includes a different config.xml file and additional libraries.
To prevent the loss of site-specific configuration information, the installer does not overwrite the config.xml file during an upgrade installation. The standard TFS config.xml file includes the MIRC plugin and pipelines for the File Service, the DICOM Service, and the TCE Service.
The additional libraries include the Apache XML libraries because the standard Java XML libraries don't support passing DOM objects as parameters to XSL transforms. This capability is used widely in TFS, but not CTP, so they are only included in the TFS installer.
3 The MIRC Plugin
All the code for TFS is in the MIRC plugin, including all the servlets, the TFS-specific pipeline stages, and many XSL, Javascript, CSS, and image files. The plugin is loaded when CTP loads the configuration, and it is started after the server is started but before any of the pipelines are started.
The root attribute of the MIRC plugin's configuration file element defines the root directory of all the TFS files. The default location is mircsite under the CTP directory, but it can be changed if it is desired to locate the teaching files on another drive or network system. Because the installer never overwrites any of the teaching file information, in most cases it is safe in the CTP directory tree.
When the plugin is started, it loads the MIRC configuration file. It then loads various databases and adds all the TFS servlets to the server. It also ensures that if the admin user exists, it has the author, publisher, and department roles. Finally, it rebuilds the RadLex index (if necessary), and starts several daemon threads to monitor the status of non-local libraries (LibraryMonitor), draft documents (DraftDocumentMonitor)), and the activity report submission process that sends information on the site to the RSNA (SummarySubmitter).
When CTP shuts down, the MIRC plugin receives a shutdown method call, which triggers the closing of all the databases.
4 The MIRC Configuration File
The MIRC plugin and the three TFS pipelines are configured in the config.xml file, but all the other configuration information for a TFS site is contained in the mirc.xml file, located in the root of the plugin (typically CTP/mircsite). The mirc.xml file contains all the configuration information for the site, all the local libraries it contains, all the non-local libraries it can query, the File Service, and the Case of the Day (if any). The file is parsed and managed by the mirc.MircConfig class. It is managed by the admin servlets for each of the major subsystems: QueryServiceAdmin, StorageServiceAdmin, and FileServiceAdmin. This file is not overwritten by the installer during an upgrade.
This is an abbreviated listing of a mirc.xml file for a test site:
<mirc UI="integrated" addresstype="dynamic" date="2012.12.23 at 09:28:28 CST" disclaimerurl="" downloadenb="yes" email="johnperry@dls.net" masthead="ChildrensLogo2.jpg" mastheadheight="109" mode="rad" popup="login" roles="department" rsnaVersion="Z97" sharestats="yes" showptids="yes" showsitename="yes" siteid="1343228846573" sitename="JP's Teaching Files" siteurl="http://192.168.0.4:80" timeout="7" version="Z105"> <Libraries> <Library address="/storage/ss1" authenb="yes" autoindex="no" dcmenb="yes" deflib="yes" enabled="yes" id="ss1" jpegquality="-1" local="yes" maxsize="75" subenb="yes" tceenb="yes" timeout="0" zipenb="no"> <title>My MIRC Site</title> <tagline/> </Library> <Library address="http://mirc.childrensmemorial.org/storage/ss12" deflib="no" enabled="yes" local="no"> <title>CMH: Children's Memorial Hospital General Pediatric Cases</title> </Library> </Libraries> <FileService maxsize="75" timeout="0"/> <news> <title>20110902 DX CHEST STUDY</title> <image> /storage/ss4/docs/20121002065223174/9999.68816769595213868527999756405838373430_base.jpeg </image> <url>/storage/ss4/docs/20121002065223174/MIRCdocument.xml</url> </news> </mirc>
4.1 The mirc Element
The mirc root element has these attributes:
- UI: the default UI of the system. Standard values are integrated and classic.
- addresstype: the addressing mode of the system. Standard values are dynamic and static. For sites that operate in dynamic mode and have a numeric IP address, the siteurl attribute is updated with the actual IP address obtained from the operating system when the system starts. For sites that operate in static mode or have a non-numeric IP address, the siteurl attribute is not modified when the system starts.
- date: the build date of the MIRC.jar file, obtained from the file's manifest when the system starts.
- disclaimerurl: the URL of a web page to be displayed if the value of the popup attribute is notes.
- downloadenb: whether to enable the DownloadService on the site. Typically, on the RSNA site has this service enabled.
- email: the email address of the site admin. This is reported to the RSNA site as part of an Activity Summary report.
- masthead: the name of the masthead file displayed in the classic UI. This file is loaded by the QueryService, and its context is query, so this file must be located in the CTP/mircsite/query directory. The default file is called manifest.jpg, and it is located in the MIRC.jar at query/masthead.jar. Unless a site has provided its own masthead, the default file is served from the jar.
- mastheadheight: the vertical height of the masthead file.
- mode: the mode in which to operate the site. Standard values are rad and vet, the latter for veterinary medicine. The choice affects the structure of the advanced query fields.
- popup: the initial popup to display when a user first accesses the site. The standard values are help, notes, login, and none.
- roles: a comma-separated list of user roles used by the site in addition to the standard roles.
- rsnaVersion: the current MIRC version running on the RSNA site, obtained from the RSNA site when the local site starts. This is compared to the local version in the About TFS popup to determine whether to indicate that a newer version is available.
- sharestats: whether to automatically submit Activity Summary reports to the RSNA site. Standard values are yes and no.
- showptids: whether to display PHI in patient elements in MIRCdocuments. Standard values are yes and no.
- showsitename: whether to overlay the sitename on the masthead in the classic UI. Standard values are yes and no.
- siteid: the unique ID of the site, assigned automatically by the system. Its value is the system time in milliseconds when the system first starts. It is used by the RSNA TFS site to collate activity reports from the various sites in the field.
- sitename: the name displayed on the query page.
- siteurl: the URL of the site, including the protocol, the IP or domain name, and the port, but no path information.
- timeout: the timeout in seconds for queries.
- version: the version of the MIRC.jar file, obtained from the file's manifest when the system starts.
4.2 The Libraries Element
The Libraries element lists all the libraries known to the system, whether local or not. Each library is represented by a Library element. Local libraries have these attributes:
- address: the URL path for the library. All local libraries have paths consisting of /storage/, followed by the library's ID.
- authenb: whether to authoring is enabled on the library. Standard values are yes and no.
- autoindex: whether documents saved on the library are to be indexed automatically. Standard values are yes and no. The attribute controls users' ability to save documents that have permissions that allow them to be seen by unauthenticated users. Such documents are called public, and the act of making a document public is called publishing. If autoindexing is enabled, then any author can publish a document. If autoindexing is not enabled, then only users with the publisher role are allowed to publish a document.
- dcmenb: whether the DICOM Service is enabled on the library. Standard values are yes and no.
- deflib: whether the library is to be included in the list of libraries queried when a user first accesses the system. Standard values are yes and no.
- enabled: whether the library is actually to be queried if it is included in the list of libraries to be searched in a query. Standard values are yes and no. This attribute is managed by the system. It is intended to suppress queries of remote libraries that are known to be down. The LibraryMonitor daemon thread periodically checks remote libraries to see if they respond and then updates the enabled attributes accordingly.
- id: the ID of the local library. This is a string consisting of ss followed by an integer. The integer is automatically assigned by the Storage Service Admin servlet when a library is created.
- jpegquality: the compression quality to be used when saving images in MIRCdocuments. Standard values range from 1 to 100. The value -1 indicates the use of the system standard quality.
- local: whether the library is local. Standard values are yes and no.
- maxsize: the maximum size of a POST upload in megabytes. The default is 75.
- subenb: whether the Submit Service is enabled on the library. Standard values are yes and no.
- tceenb: whether the TCE Service is enabled on the library. Standard values are yes and no.
- timeout: the maxmum time in days to store a draft document before automatically deleting it in the DraftDocumentMonitor. A zero value indicates to keep draft documents forever.
- zipenb: whether the Zip Service is enabled on the library. Standard values are yes and no.
The Library element can have two child elements:
- title: the name to be displayed for the library in query results and on admin pages.
- tagline: an optional short description of the library to be displayed on query results pages in the classic UI.
4.3 The FileService Element
The FileService element configures the File Cabinets.
- maxsize: the maximum size of a POST upload in megabytes. The default is 75.
- timeout: the maxmum time in days to retain a file in the Shared File Cabinet before automatically deleting it. A zero value indicates to keep shared files forever.
4.4 The news Element
The optional news element specifies a link to a MIRCdocument, along with the title and a representative image. These are displayed on the query page, allowing a user to click the title or the image and go directly to the document without going through a query. This element is updated by an admin clicking on the Case of the Day button on a MIRCdocument. It is removed by checking a box on the Query Service Admin page.
5 The MIRC Servlet
The main purpose of the MIRC servlet (mirc.MircServlet) is to redirect requests to the /query path. This is just for backward compatibility with the Tomcat/MIRC version.
The servlet context is mirc.
When called with the /mirc path, it redirects the request.
If additional path information is provided in the request, it has several other functions:
- When called with the /mirc/roles path, it returns a comma-separated list of the defined roles on the system. Defined roles are just those additional roles listed in the mirc.xml file.
- When called with the /mirc/roles/xml path, it returns an XML structure containing a list of all the roles on the system, including defined roles and the roles built into the User Manager.
- When called with the /mirc/version path, it returns the version of the MIRC.jar file as defined in its manifest.
- When called with the /mirc/libraries path, it returns an XML structure containing a list of all the Libraries on the system, with the address attributes of local libraries updated to include the value of the siteurl attribute. The order of the Library elements is alphabetical by their title elements.
- When called with the /mirc/sortedlibraries path, it returns an XML structure containing a list of all the Libraries on the system, with the address attributes of local libraries updated to include the value of the siteurl attribute. The order of the Library elements is alphabetical by their title elements, except that all the local libraries come first.
- When called with the /mirc/phi path, it returns the contents of the Access Log, a file that is typically stored as CTP/mircsite/phi/AccessLog.txt. This function is only available to users with the admin role.
6 Users, Roles, and Preferences
TFS users have accounts defined in the CTP/users.xml file. A user has a username, a password, and a set of roles.
Access to user accounts is provided by the org.rsna.server.Users class. This class has two subclasses, one that authenticates passwords as stored in the XML file and one that authenticates passwords against an external LDAP server. (See the Server article for more information.)
The admin user has access to a User Manager Servlet to create or delete accounts, and to assign roles to users. The CTP application assigns the standard org.rsna.servlets.UserManagerServlet to the context /users before it starts the plugins and pipelines, but the MIRC plugin subsequently overrides that context with the mirc.users.MircUserManagerServlet.
In addition to an account, a user also has a set of preferences that are unique to TFS. The preferences are stored in the JDBM CTP/mircsite/preferences database. Users have access to the Preferences Servlet to manage their preferences.
6.1 MircUserManagerServlet
The mirc.users.MircUserManagerServlet allows the admin user to manage the CTP/users.xml file. It also allows the admin user to enter certain preferences (person name, affiliation, and contact) on behalf of a user.
The servlet allows the admin user to set passwords for users, but if the server is configured for LDAP authentication, these passwords are ignored. The servlet provides no way to update passwords in an LDAP server.
6.2 PreferencesServlet
The mirc.prefs.PreferencesServlet allows an individual user to manage the preferences database entry for his account. It also provides a way for a user to change his password, although as noted above, passwords in the CTP/users.xml file are ignored in servers configured to use LDASP authentication.
The managed preferences are:
- UI: the individual user's choice of UI (classic or integrated). This choice overrides the site default as soon as the user is authenticated. This preference is automatically updated whenever the user changes the UI through either the Classic UI lin in the footer of the Integrated UI query page or the Switch to Integrated User Interface menu item in the Help menu of the Classic UI. Thus, the system always provides the user the last UI in effect when the user last accessed the system.
- Password change
- Personal information: the information that is used to populate the author element when a user creates a MIRCdocument. The person name is also displayed in the header bar of the Integrated UI. This information can be updated by the admin user through the MircUserManagerServlet. This information is also automatically updated when the user creates a MIRCdocument through one of the author services.
- Name: the person name
- Affiliation: normally the user's department or university name
- Contact: normally the user's email address or phone number
- MyRSNA credentials: the username and password of the user's MyRSNA account. These credentials are used by the server to upload MIRCdocuments to the user's MyRSNA Files.
- Export destinations: a list of destination URLs and credentials for use in exporting MIRCdocuments from one library to another (possibly on a different server).
7 QueryService
The Query Service is the primary portal into TFS. It is implemented in the mirc.query.QueryService class, which extends org.rsna.servlets.Servlet. The doGet method has three important responsibilities:
- It verifies that the request used the same URL that is known to the site, and it redirects the request to the site URL if it did not. This is necessary to ensure that session information will be passed to the Storage Service when a document is viewed.
- A successful login generates a Set-Cookie for the RSNASESSION cookie. This cookie carries the information that authenticates a request as belonging to a specific user session. Browsers supply cookies in requests based on the text of the URL. Thus, a cookie that was set for 127.0.0.1 will not be supplied in a request using 192.168.0.4, even if the two IP addresses refer to the same system. When a user clicks on a query result to view a MIRCdocument, the URL is based on the site URL. If the MIRCdocument requires authentication, it is important that the RSNASESSION cookie be supplied in the request to enable the Storage Service to obtain the user's roles. Thus, it is critical that all the requests use the site URL.
- It determines whether the request includes a query, in which case it services the query as if it had been received as a POST.
- If the request did not include a query, it generates a query page based on the selected UI.
The mirc.query.UI interface is implemented by two classes: mirc.query.ClassicUI and mirc.query.IntegratedUI. Each class generates a page using an XSL transform obtained from the MIRC.jar file:
- /query/ClassicUI.xsl
- /query/IntegratedUI.xsl
The Query Service handles queries in the serviceQuery method. This is called from either the doGet or doPost methods depending on the request. The serviceQuery method first constructs an XML object from the parameters of the request, and then transforms that object into an XML object in the MIRCquery schema. (See The MIRCquery Schema for more information.)
The Query Service instantiates one mirc.query.MircServer object for each library (local or remote) to be queried and passes it the MIRCquery XML object. The MircServer objects are separate threads that handle the connection to the library and the receipt of the query results.
Once all the MircServers have been started, the Query Service polls them to see when all have finished receiving their query results. The whole process respects the value of the timeout obtained from the singleton MircConfig object that encapsulates the MIRC configuration.
When the MircServers have finished, the Query Service assembles a single XML object containing all the query results. The query results are returned in one of three forms, depending on the parameters of the query:
- In the Integrated UI, a query is an AJAX call, and the query results XML object is returned directly, and the Javascript programmatically populates the query results table on the query page.
- In the Classic UI, normal results are in the form of a page showing a list of links to matching MIRCdocuments. The page is constructed by transforming the query results XML object with the /query/MIRCqueryresult.xsl program.
- In the Classic UI, Case Navigator results are in the form of a page with a header bar providing navigation and a main body showing a matching MIRCdocument. The page is constructed by transforming the query results XML object with the /query/CaseNavigatorResult.xsl program.
In the Integrated UI, it is possible to select one or more MIRCdocuments from the query results table and click an icon to display the selected documents in the Case Navigator. This is performed by the mirc.casenav.CaseNavigatorService servlet. This servlet simply constructs an XML object containing the selected documents and then transforms it using the /query/CaseNavigatorResult.xsl program, resulting in the requested page.
7.1 QueryServiceAdmin
The mirc.qsadmin.QueryServiceAdmin servlet provides a UI for managing the CTP/mircsite/mirc.xml file. The doGet method generates a page containing a form, and the doPost method updates the file from the form parameters. The servlet does not write the file directly; it makes calls to the singleton mirc.MircConfig object to do the updates and write the file.
8 StorageService
The mirc.storage.StorageService servlet is the primary interface into the stored MIRCdocuments in the system. It responds to requests whose paths start with /storage.
In general, a request URL has one of two forms:
- /storage/{function}/{ssid}/{MIRCdocumentPath}
- /storage/{ssid}/{MIRCdocumentPath}?{query}
where:
- {function} is a function name. The only supported function is delete.
- {ssid} is the identifier of the local library containing the MIRCdocument. All {ssid} path elements start with ss, which allows them to be distinguished from {function} path elements.
- {MIRCdocumentPath} is the path to the MIRCdocument from the root of the library.
Local libraries are stored in root directories in this structure
- CTP/mircsite/storage/{ssid}
The from the root of a library to a MIRCdocument always starts with docs.
Each MIRCdocument in a library is stored in its own directory. The directory contains the MIRCdocument's XML file and any files that it references. The referenced files are typically images, but there is no restriction on the types of files that can be referenced.
The doGet method provides different responses depending on the requested resource, the supplied query parameters, and the requesting user's roles.
- If the request calls the delete function, it deletes the MIRCdocument. (I know that this is not RESTful, but it grew up organically, and it might be nice to implement the rest of the RESTful methods in the server and then reflect that in all of TFS, but that's for someone else to do.)
- If the requested resource has the .dcm extension, there are several possibilities, depending on the query parameters:
- If the dicom query parameter is supplied (with or without a value), a web page is generated listing the DICOM elements.
- If the params query parameter is supplied (with or without a value), an XML structure is returned listing several key technical parameters of the DICOM object. This feature is used in the Advanced Author Service on the pane that allows a user to change the WW/WL values of an image.
- If the jpeg query parameter is supplied (along with parameters specifying a frame number, a compression quality value, and WW/WL values), a JPEG image is returned with the requested characteristic of the DICOM object. This feature is used in the Advanced Author Service on the pane that allows a user to change the WW/WL values of an image.
- If the update query parameter is supplied (along with parameters specifying a frame number, a compression quality value, and WW/WL values, plus parameters identifying the MIRCdocument XML file and whether to update only the requested resource or all images of the same series), a background thread is started to update the WW/WL values of the identified images. This feature is used in the Advanced Author Service on the pane that allows a user to change the WW/WL values of an image.
- If the bi query parameter is supplied (with or without a value), an attempt is made to return a serialized BufferedImage. This feature does not work because BufferedImage is not serializable. The code is left in place against the day when somebody figures out how to do it.
- If none of the above conditions are met, the servlet returns the requested resource with the Content-Type application/dicom.
- If the requested resource has the .xml extension, there are several possibilities, depending on the root element name and the query parameters:
- If the root element name is not MIRCdocument, the servlet returns the requested resource with the Content-Type text/xml;charset=UTF-8.
- If the ppt query parameter is supplied (with or without a value) and the user has the export privilege on the MIRCdocument, the servlet creates a presentation file for the requested resource and returns it with the Content-Type application/vnd.openxmlformats-officedocument.presentationml.presentation and a Content-Disposition allowing the file to be saved as a .odp file.
- If the zip query parameter is supplied (with or without a value) and the user has the export privilege on the MIRCdocument, the servlet creates a zip file for the MIRCdocument and returns it with the Content-Type application/zip and a Content-Disposition allowing the file to be saved. If the ext parameter is present, its value is used as the extension of the file; otherwise, the extension is .zip.
- If the xsl query parameter is supplied (with or without a value), the servlet filters the PHI out of the MIRCdocument and returns the resulting XML with Content-Type text/xml;charset=UTF-8. There is no requirement that the user have the export privilege on the MIRCdocument. The reason is that this feature is used by third-party phone and tablet apps to obtain the XML so they can render it themselves. Note: the filter operation is by-passed if the user is the owner of the MIRCdocument.
- If none of the above conditions are met, the servlet transforms the MIRCdocument XML using the /storage/MIRCdocument.xsl resource from the MIRC.jar and returns it with Content-Type text/html;charset=UTF-8.
The doPost method responds to queries from Query Services. It expects a MIRCquery XML structure with the Content-Type text/xml, and it returns a MIRCqueryresult XML structure. The query is implemented by searching the indexes of the libraries identified in the MIRCquery.
The index of all libraries is encapsulated by the mirc.storage.Index class. This class has a static getInstance(String ssid) method that returns a singleton instance of the index of the specified library. Each library index is a JDBM database that contains many HTrees that index specific MIRCdocument schema elements, plus HTrees that are used for free text queries. All the library indexes are stored in the CTP/mircsite directory.
The HTrees include each word indexed, plus all substrings of the word. This mechanism is the most efficient that has been implemented to date in TFS; nevertheless, it is possible that a change to SOLR would provide greater efficiency as well as additional features. When this change is made, a new mirc.storage.Index class should be all that is needed to interface it to the rest of TFS.
8.1 StorageServiceAdmin
The mirc.ssadmin.StorageServiceAdmin servlet provides a UI for managing the library parameters in the CTP/mircsite/mirc.xml file. The doGet method generates a page containing a form, and the doPost method updates the file from the form parameters. The servlet does not write the file directly; it makes calls to the singleton mirc.MircConfig object to do the updates and write the file.
The servlet allows the admin user to create and delete libraries. When deleting a library, the references to the library in the CTP/mircsite/mirc.xml file are removed; neither the index nor the stored MIRCdocuments of the library are deleted.
8.2 Support Services
There are several other servlets that are related to the Storage Service, so they are described here.
8.2.1 AddImagesService
The mirc.addimg.AddImagesService servlet allows a user with the update privilege on a MIRCdocument to add images to it.
The servlet context is addimg. It is triggered by clicking the Add images to this Document button on the MIRCdocument.
The servlet contains only a doPost method. The method receives a POST with Content-Type multipart/form-data containing files from the client to add to the MIRCdocument. The method that inserts the files automatically unpacks zip files and inserts their contents.
After adding the files, the servlet redirects the client to the MIRCdocument so it will be rendered with the new files.
8.2.2 SortImagesService
The mirc.sort.SortImagesService servlet allows a user with the author role and the update privilege on a MIRCdocument to sort the images in the image-section by a series of keys:
- StudyDate
- StudyTime
- StudyInstanceUID
- SeriesInstanceUID
- AcquisitionInstanceUID
- InstanceNumber
The servlet context is sort. It is triggered by clicking the Sort the Image Section button on the MIRCdocument.
The sorting is accomplished in the sortImageSection method of the mirc.util.MircDocument class.
The servlet contains only a doGet method.
After sorting the image-section and saving the file, the servlet redirects the client to the MIRCdocument so it will be rendered with the images in the new order.
8.2.3 CommentService
The mirc.comment.CommentService servlet allows a user with the author role to create comment threads in and post comments to a MIRCdocument.
The servlet contains only a doPost method.
The servlet context is comment. It responds to two URLs:
- /comment/newthread
- /comment/newpost
A collection of comment threads is encapsulated in a threadblock element in the MIRCdocument. A threadblock element is uniquely identified by an id attribute.
Comment threads are encapsulated in thread elements in the MIRCdocument. They are uniquely identified by an id attribute. The newthread command requires two query parameters:
- threadblockID
- threadtitle
Individual posts to a thread are encapsulated in post child elements of the thread element. They appear in the order in which they were inserted, and they are not uniquely identified. The newpost command requires two query parameters:
- threadID
- posttext
The servlet obtains the username from the request and then gets the user's person name from the preferences database. It includes that information as well as the current date in the XML that is added to the MIRCdocument.
After inserting the thread or post and saving the file, the servlet redirects the client to the MIRCdocument so it will be rendered with the changes.
8.2.4 RevertService
The mirc.revert.RevertService servlet allows a user with the update privilege on a MIRCdocument to change it from a completed case to a draft case.
The servlet contains only a doGet method.
The servlet context is revert. It is triggered by clicking the Revert to draft status button on the MIRCdocument.
A draft case is one for which the MIRCdocument root element has the temp attribute set to yes. Normally, a draft case is created automatically by the DICOM Service or the TCE Service. When a draft case is opened and then saved, the Advanced Author Tool converts it to a completed case by removing the temp attribute and storing it in a different folder from the one automatically created for it when it was first constructed. At the same time, the tool adds the draftpath attribute pointing to the location it had as a draft document.
- The DICOM Service inserts DICOM images into a MIRCdocument (creating the MIRCdocument if necessary) based on one of the elements in the image. If the DICOM Service is operated in the patient-centric mode, the element used to construct the folder for the MIRCdocument is the PatientID. If the service is operated in the study-centric mode, the element is the StudyInstanceUID. Once a MIRCdocument has been converted to a completed case, the document is in a different folder, so subsequent images for the same patient or study will cause the creation of a new draft document. The purpose of the RevertService is to allow a document to be switched back to the draft status so new images can be added through the DICOM Service.
Conversion back to the draft status is only possible if the draftpath attribute is available in the root element. Once the conversion is done, the URL of the document changes to the one it had when it was originally created as a draft case, and the URL it had as a completed case is no longer valid.
After converting the document to a draft case, the servlet redirects the client to the MIRCdocument so it will be loaded from the new location.
8.2.5 PublishService
The mirc.publish.PublishService servlet allows a user with the publisher role to make a MIRCdocument public. Making a MIRCdocument public is done by inserting an asterisk in the MIRCdocument/authorization/read element. Public documents can be viewed by unauthenticated users.
The servlet contains only a doGet method.
The servlet context is publish. It is triggered by clicking the Publish button on the MIRCdocument.
When publishing a document, the service removes the publication request, if present, from the document.
- A publication request is indicated by setting the pubreq attribute of the root element to yes. This is done automatically when a non-publisher attempts to publish a document on a library for which the autoindexing is not enabled.
After publishing the document, the servlet redirects the client to the MIRCdocument so it will reflect the public status.
9 ConferenceService
The mirc.confs.ConferenceService servlet provides access to a JDBM database of conferences, organized into two categories:
- Shared conferences are accessable by unauthenticated users
- Personal conferences are visible only to the user who created them.
The database is implemented in the mirc.confs.Conferences class. The database is contained in the CTP/mircsite/conferences.db file.
A conference is implemented in the mirc.confs.Conference class. A conference may contain both child conferences and agenda items, providing a hierarchy.
Agenda items are implemented in the mirc.confs.AgendaItem class. An agenda item is essentially a link to a resource. In most cases, the resource is a MIRCdocument, but it is possible to have an agenda item that is simply a URL pointing to any web resource.
The servlet context is confs.
The servlet contains only a doGet method.
- When accessed with the /confs path, the servlet returns a web page with a left pane for navigating the hierarchy of public and personal conferences.
- When accessed with the /confs/casenavigator path, the servlet returns a web page showing the agenda items in the Case Navigator format (as if the user had done a query that resulted in the list of MIRCdocuments that are in the conference).
- All other paths return XML structures. These requests come from Javascript AJAX calls on the query pages or on the Conference Service page.
- The current implementation suffers from two significant problems:
- Agenda items do not know the permissions of the target resource, so restricted documents may be listed for users who do not have permission to view them.
- If a MIRCdocument is deleted, the conferences in which it appears are not notified to delete the corresponding agenda items.
- If the storage index is changed to SOLR, it would be wise to consider changing the conference mechanism so the information is normalized.
10 FileService
The mirc.files.FileService servlet provides access to directory trees of files, organized into two categories, called file cabinets:
- The Shared file cabinet is accessable by all authenticated users
- Personal file cabinets are visible only to an individual user.
The purpose of the File Service is to allow users to store files of any kind, outside the structure of the MIRCdocument libraries.
The root of the hierarchy is CTP/mircsite/files.
- The root of the Shared file cabinet is CTP/mircsite/files/Shared.
- The root of a user's Personal file cabinet is CTP/mircsite/files/Personal/{username}.
Within a file cabinet, there are two subfolders, one for files, and one for icons that are displayed when the contents of a file cabinet are shown on a web page.
- CTP/mircsite/files/Personal/{username}/Files
- CTP/mircsite/files/Personal/{username}/Icons
The two subfolders have exactly the same structure. For each leaf file in the Files tree, there is a corresponding leaf file in the Icons tree, with the same name, but with an appended extension (.jpg or .gif). For example, these two files correspond:
- CTP/mircsite/files/Personal/{username}/Files/folder1/folder2/file.dat
- CTP/mircsite/files/Personal/{username}/Icons/folder1/folder2/file.dat.jpg
The servlet context is files.
The servlet allows the admin user to create and delete libraries. When deleting a library, the references to the library in the CTP/mircsite/mirc.xml file are removed; neither the index nor the stored MIRCdocuments of the library are deleted.
The servlet contains both doGet and doPost methods for managing the file cabinets, creating and deleting subfolders, uploading, downloading files, and deleting files, etc. For DicomObjects, it also provides a an element listing page. As in all TFS upload functions, if the user uploads a zip file, the file is automatically unpacked and its individual files are put into the file cabinet. This process is not recursive, so it is possible to put a zip file into a file cabinet by encapsulating it in another zip file before uploading it.
The File Service also has a DICOM Storage SCP to allow files to be received from a PACS or DICOM workstation and stored in the file cabinets. The function is implemented in a CTP pipeline. See File Service Pipeline for details.
10.1 FileServiceAdmin
The mirc.fsadmin.FileServiceAdmin servlet provides a UI for controlling the maximum upload size for files and for setting the maximum time files are kept in the Shared file cabinet before being automatically deleted.
The automatic deletion mechanism is implemented in the mirc.fsadmin.SharedFileCabinetManager class. That class is a daemon thread that periodically looks for files that are older that the specified maximum and deletes them.
11 Author Services
TFS contains several mechanisms for manually creating MIRCdocuments.
11.1 The Advanced Author Service
The mirc.aauth.AuthorService servlet provides a UI for creating MIRCdocuments from a template. Templates are described in detail in MIRC Templates. The Advanced Author Service is the most complete authoring tool of all the TFS authoring tools; it supports all the elements described in The MIRCdocument Schema.
The context of the servlet is aauth.
The doGet method provides different responses depending on the path.
- The /aauth/{ssid} path displays the template selection page, listing the user's preferences for person name, affiliation, and contact, plus an option for choosing a template to serve as the starting point for creating a new MIRCdocument. The templates are contained in MIRC.jar in the /aauth/templates directory. They are copied to the disk into the CTP/mircsite/aauth directory when required. On the template selection page, an example of the format of the MIRCdocument tempate is displayed when the template is selected. The example images are in MIRC.jar in the /aauth/tokens directory.
- The /aauth/{ssid}/{librarypath}/{MIRCdocument}.xml path opens the MIRCdocument in the editor window.
The doPost method handles three general cases, depending on the request path and whether the request includes the docText parameter.
- If the request path is /aauth/{ssid} and the the docText parameter is missing, the request is a POST from the template selection page, in which case the servlet opens the selected template in the editor window. At this time, the servlet also copies the user's person name, affiliation, and contact information from the form parameters to the user's preferences.
- If the request path is /aauth/{ssid} and the docText parameter is present, the request is a POST of the content of a new MIRCdocument, in which case the servlet creates a new directory in the specified library, saves the text of the docText query parameter as the MIRCdocument.xml file, and then inserts any files identified in the XML from the file cabinets.
- If the request path is /aauth/{ssid}/{librarypath}/{MIRCdocument}.xml and the docText parameter is present, the request is a POST of the edited contents of an existing MIRCdocument, in which case there are two cases:
- If the original document was a draft document (as indicated by the root element having the temp="yes" attribute), then the document is first moved to a different directory in the same library. Then, the servlet replaces the text of the original MIRCdocument with the text of the docText parameter, and then inserts any files identified in the XML from the file cabinets. See the Revert Service section for more information about draft documents.
- If the original document was not a draft document, the servlet replaces the text of the original MIRCdocument with the text of the docText parameter, and then inserts any files identified in the XML from the file cabinets.
When processing the text of a docText parameter, the servlet first saves it to the appropriate file and then instantiates an org.util.MircDocument object from the file. It then uses that object for subsequent modifications and save operations.
In the text of the docText parameter, references to files in the file cabinets are src, href, or docref attributes that have the form "[path]", where path starts with either Shared or Personal. When such references appear, the servlet copies the files from the file cabinets to the MIRCdocument's directory and changes the attribute values to point to the files in that location.
The editor window is generated by an XSL transform using the /aauth/Editor.xsl program in MIRC.jar. This program produces an HTML page that references several Javascript files from either MIRC.jar or util.jar. The principal Javascript file is /aauth/Editor.js.
11.2 The Basic Author Service
The mirc.bauth.BasicAuthorService servlet provides a UI for creating MIRCdocuments from a template. Templates are described in detail in MIRC Templates. The Basic Author Service is a very simplified authoring tool. It provides no means for adding elements to the document that are not in the template. Further, whereas the Advanced Author tool has access to files stored in the file cabinets, the Basic Author tool requires that any files added to the document when it is created are uploaded from the client. A common use of the Basic Author tool is to create an initial version of the document. The document is then opened in the Advanced Author tool for adding content beyond what was supported by the template.
The context of the servlet is bauth.
The doGet method responds to the /bauth/{ssid} path and provides a form for selecting a template and entering information into the document. The templates are contained in MIRC.jar in the /bauth directory. They are copied to the disk into the CTP/mircsite/bauth directory when required. The form is generated by an XSL transform using the /bauth/BasicAuthorService.xsl program in MIRC.jar. This program produces an HTML page that references several Javascript files from either MIRC.jar or util.jar, but the page does not have the complex interactivity of the Advanced Author tool's Editor page. The principal Javascript file is /bauth/BasicAuthorService.js.
The doPost method receives the form parameters and any posted files and creates the MIRCdocument in the selected library.
11.3 The Submit Service
The mirc.submit.SubmitService servlet provides an interface for uploading MIRCdocument zip files into the system. MIRCdocuments exported from the system are encapsulated in zip files in a format described in The MIRC Protocol for Document Exchange. The Submit Service is used to import these zip files and store them in libraries. Some third-party authoring tools also use it to save MIRCdocuments on the system.
The context of the servlet is submit.
The doGet method responds to the /submit/{ssid} path and provides a form for uploading a zip file. The form is generated by an XSL transform using the /submit/SubmitService.xsl program in MIRC.jar.
The doPost method receives the form parameters and any posted files and inserts the MIRCdocument in the selected library. It accepts two Content-Types:
- multipart/form-data
- application/x-zip-compressed
If the Content-Type is application/x-zip-compressed, the content of the file is read directly from the input stream. This is the Content-Type typically used by third-party authoring tools. To further assist third-party tools, the doPost method parses additional path elements in the request and recognizes several form parameters:
- If a path to an existing MIRCdocument is included in the request path, the submission is treated as an update; otherwise, it is treated as the creation of a new MIRCdocument.
- If the preserveOwners parameter is supplied, no change is made to the ownership of the MIRCdocument; otherwise, the submitting user becomes the owner.
- if the suppress parameter is supplied, the response is a simple text string listing the results of the submission; otherwise, the response is another form page alloowing the user to submit another MIRCdocument.
If the submitted MIRCdocument is public and the submitting user does not have the publisher role (and autoindex is not enabled on the library), the read permission is modified appropriately and a publication request is entered in the document.
If the submitted MIRCdocument is a draft document, its draft status is removed, making it a completed case. This is consistent with the operation of the Advanced Author Tool. If the document contains a draftpath attribute, it is removed, making it impossible for the document to be returned to draft status. This is done to ensure that a document moved from one library to another (or from one site to another) cannot produce unexpected results when reverted to draft status.
11.4 The Zip Service
The mirc.zip.ZipService servlet provides an interface for uploading non-MIRCdocument zip files into the system and automatically creating MIRCdocuments from them. The initial motivation for the Zip Service was to provide a way to import an institution's library of teaching file cases into a TFS site. Before digital modalities dominated radiology, such libraries were cabinets of folders containing films. As digital modalities began to take over most radiology procedures, these cabinets became directory trees, typically organized by body part or specialty, with leaf directories containing image files and sometimes text documents for a single case. The Zip Service accepts a zip file containing a directory tree and creates one MIRCdocument for each directory in the tree that contains at least one image.
Some third-party authoring tools use the Zip Service for submission of the MIRCdocuments they create. The advantage of the Zip Service for this purpose is that it absolves the authoring tool from the responsibility to create JPEG images for each of the DICOM images in the MIRCdocument. The disadvantage is that the Zip Service can only be used to create a MIRCdocument, not to update it.
The context of the servlet is zip.
The doGet method responds to the /zip/{ssid} path and provides a form for uploading a zip file. The form is generated by an XSL transform using the /zip/ZipService.xsl program in MIRC.jar. The form allows the submitting user to define the owner and permissions for all the created MIRCdocuments.
The doPost method receives the form parameters and the posted zip file and initiates a background thread (mirc.zip.ZipThread) that creates the MIRCdocuments in the selected library.
The Zip Service accepts two Content-Types:
- multipart/form-data
- application/x-zip-compressed
If the Content-Type is application/x-zip-compressed, the content of the file is read directly from the input stream. This is the Content-Type typically used by third-party authoring tools.
After receiving the submission, the Zip Service returns a response that depends on the Content-Type.
- If the Content-Type was multipart/form-data, it returns the form allowing the user to submit another zip file.
- if the Content-Type was application/x-zip-compressed, it returns a text status string.
The ZipThread creates MIRCdocuments from a template file. The default template is located in CTP/mircsite/zip/template.xml. As it walks the directory tree of the zip file submission, if it encounters a template.xml file in any directory, it uses that file for all MIRCdocument creations in that directory or any of its subdirectories. For each MIRCdocument created, it uses the name of the directory as the content of the title element, and it includes the names of all the parent directories in the keywords element.
11.5 Author Summary
The mirc.summary.AuthorSummary servlet provides an interface for listing the documents created in a library by an author (or all authors) in a date range. It can produce the output as HTML, XML or CSV.
The context of the servlet is summary.
The doGet method responds to the /summary/{ssid} path and provides a form for uploading a zip file. The form is generated by an XSL transform using the /summary/AuthorSummary.xsl program in MIRC.jar.
The doPost method receives the form parameters and produces the output in the selected format. To produce a result, the servlet gets the list of all documents from the index of the selected library and then filters it programmatically based on the form parameters.
The servlet restricts a user to his own documents unless the user has the summary role.
12 The MIRC Pipelines
There are three standard pipelines built into TFS. Each receives data objects from external sources (typically a PACS or workstations) and stores them in the system. The pipelines use standard CTP stages for receiving and anonymizing the data objects. The MIRC plugin contains special pipeline stages to implement the storage function. For information on configuring these pipelines, see MIRC Pipelines.
12.1 File Service Pipeline
The File Service Pipeline receives data objects via DICOM, anonymizes them, and stores them in the File System. The storage stage is implemented in the mirc.stages.MircFileStorageService class. The pipeline uses the Called AE Title to determine whether to store the files in the Shared File Cabinet or a specific user's Personal File Cabinet.
12.2 DICOM Service Pipeline
The DICOM Service Pipeline receives data objects via DICOM, anonymizes them, and stores them in MIRCdocuments. The storage function is implemented in the mirc.stages.MircDocumentStorageService class. The pipeline uses the Called AE Title to determine the destination library in which to store the objects. The storage stage selects the MIRCdocument in which to store the object based on the value of a DICOM element that is identified by the caseTag attribute of the stage's configuration file element. The standard configuration groups objects into MIRCdocuments based on the PatientID element. In this mode, the pipeline is said to implement the "patient-centric workflow".
The storage stage creates a new MIRCdocument when one does not already exist to store the object. New MIRCdocuments are created from a template defined by the templateName attribute of the stage's configuration file element. The default value is DicomServiceTemplate.xml. Templates for a library must be stored in the library's root directory (e.g. CTP/mircsite/storage/{ssid}).
- Note: It is also possible to group objects by study by setting the caseTag attribute to StudyInstanceUID.
12.3 TCE Service Pipeline
The TCE Service Pipeline receives data objects via DICOM, anonymizes them, and stores them in MIRCdocuments. The pipeline is an implementation of the IHE Teaching Files and Clinical Trials Integration Profile, and it provides both the Export Manager and Export Receiver actors.
The storage function is implemented in the mirc.stages.TCEStorageService class. The pipeline uses the Called AE Title to determine the destination library in which to store the objects. The storage stage groups data objects into MIRCdocuments as defined in the TCE Manifest KOS object.
The storage stage creates a new MIRCdocument for each manifest object it receives. MIRCdocuments are created from a standard template (TCEServiceTemplate.xml). There is no provision for changing this template in the configuration. The template for a library must be stored in the library's root directory (e.g. CTP/mircsite/storage/{ssid}). The template is loaded from the MIRC plugin when required.
The pipeline supports an extension to the profile, allowing the manifest to be sent as an XML MIRCdocument template. When an XML manifest is received, the manifest serves as the template for creating the MIRCdocument, so in this case the standard template is not used. This extension is used by Brigham and Women's Hospital to implement TCE on a PACS that doesn't have the ability to create a TCE Manifest KOS object.
13 ResetService
The mirc.reset.ResetService servlet allows an admin user to reset the DICOM Service and TCE Service templates in all the libraries to the latest versions provided in the MIRC plugin. Wheen resetting a template, the ResetService makes a backup of the existing version before overwriting it with the new one. After resetting all the templates, the service then clears the cache so subsequent accesses of the templates will use the new ones.
14 DownloadService
The mirc.download.DownloadServlet provides a UI for downloading the files contained in the CTP/ROOT/download directory.
The DownloadService is intended to be used for software distribution on the RSNA TFS site, but it is included in all releases. By default, it is disabled when a site is first installed, and it must be enabled on the Query Service Admin page.
The context of the servlet is download.
The doGet method responds to the /download path and provides a page containing a table listing all the files in the CTP/ROOT/download directory.
- For each .jar file, it obtains the values of the Build and Description attributes from the jar manifest.
- For each file that parses as a CTP ZipObject, it obtains the values of the Build and Description attributes from the ZipObject manifest.
- If it cannot obtain a description from the file, it looks for a file with the same name but the extension .txt and uses its contents as the description. (For example, the description of the TFS-installer-Windows.exe file is contained in the TFS-installer-Windows.exe.txt file.)
The page is generated by constructing an XML object with the necessary information and transforming it with the /download/DownloadServlet.xsl program from the MIRC plugin.
The doGet method responds to the /download/{filename} path by returning the file. It also makes an entry in a JDBM database to log the download. The database is implemented in the mirc.download.DownloadDB class. Entries in the database are mirc.download.Entry objects.
In the footer of the download page, there are links provided to users with the admin or update roles. The links allow the users to view the database and to access a page containing a form for uploading a file to the CTP/ROOT/download directory.
The doPost method receives a file from the upload page and stores it in the CTP/ROOT/download directory.
15 Activity Report
The mirc.activity.ActivityReport servlet displays various reports based on the contents of a JDBM database that tracks activity on the system. The database is implemented in the singleton mirc.activity.ActivityDB class. Many system functions report their activity to the database's methods that increment counters of various activities. Activity is tracked in the database on a monthly basis.
The context of the servlet is activity.
The servlet provides only a doGet method that responds to the /activity path. It has many functions, depending on the remainder of the path. The servlet is decidedly not RESTful.
- /activity displays the activity report.
- /activity?format=html same as above.
- /activity?format=xml returns the report in XML.
- /activity/check returns recent or old depending on whether an activity summary report has been sent to the RSNA within the last week. (Content-Type: text/plain;charset=UTF-8)
- /activity/update updates the time of the last summary report submission to the RSNA. This function is used when the summary report is submitted by a client rather than by the server. This occurs when the server is blocked off from the internet but the client isn't.
- /activity/submit?report=... receives a summary report and enters it in the activity database. Summary reports received in this way are stored in a separate table in the activity database, indexed by the sending site's ID. This function is only available on the RSNA site. It is used to receive reports from the field sites. (This is the non-RESTful part.)
- /activity/users?date=...&ssid=... displays a table showing the users who were active on the specified library during the specified month.
- /activity/users/xml?date=...&ssid=... returns the report in XML.
- /activity/user?date=...&ssid=...&username=... displays a table listing the documents viewed by the specified user on the specified library during the specified month.
- /activity/documents?date=...&ssid=... displays a table listing the documents that were viewed on the specified library during the specified month.
- /activity/documents/xml?date=...&ssid=... returns the report in XML.
- /activity/summary/html displays the contents of the summary table.
- /activity/summary/xml returns the report in XML.
- /activity/summary/csv returns the report in CSV.
- /activity/summary same as above.
The various reports are generated by XSL programs in the /activity directory of MIRC.jar.
16 RadLex
Whenever a MIRCdocument is indexed, whether on initial creation or during an update, the addDocument method of the singleton mirc.storage.Index class calls the insertRadLexTerms method of the mirc.util.mircDocument class. That method removes all term elements (preserving their children) and then processes the entire text of the MIRCdocument, wrapping RadLex terms in new term elements.
To make this process efficient, TFS keeps a JDBM database containing RadLex terms organized in a B-tree indexed by the first word of the RadLex term. The database is stored in CTP/mircsite/storage/RadLexIndex.db. When multiple RadLex terms start with the same first word, the order of the terms in the B-tree is longest first. The database is implemented in the mirc.util.RadLexIndex class. This class is a collection of static methods for managing and searching the database. The most important methods are:
- loadIndex starts a background thread that compares the last modified date of the database to that of the MIRC.jar file. If the database is older than the jar, it deletes the database and creates a new one from the mirc/radlex.xml file in the jar. That file was built by a separate utility (RadLexXML) that put the terms in the optimum order. Whenever it is necessary to update the RadLex database, the utility must be run again and a new TFS release created. This isn't very pretty, but it has not been possible to get a usable XML file from the RadLex project, so it's the best we have for now. The RadLexXML utility is available on GitHub at https://github.com/johnperry/RadLexXML).
- getSuggestedTerms returns an XML structure containing term elements for all database entries whose keys start with a supplied string.
The mirc.radlex.RadLexSuggest servlet provides a UI for searching the RadLexIndex. Nothing in TFS uses this servlet, and there is no reference to it in any of the UIs, but the servlet is loaded with the context radlex, and it can be accessed with the URL /radlex?key=.... The servlet returns an XML structure obtained from RadLexIndex.getSuggestedTerms. This servlet was requested by third-party author tool developers, but it isn't known whether it is actually used. In any case, it's useful for examining the database during testing.
17 MircDocument
The mirc.util.MIRCdocument class contains many methods for creating, modifying, and saving the MIRCdocument XML structure. This is the most important class for managing an individual MIRCdocument. In addition to constructors of various signatures, it has methods for inserting objects of various types into the MIRCdocument. When inserting a DICOM image, it creates all the necessary browser-viewable images and executes any MIRCdocument DICOM commands that pull data from the DICOM object and insert it into the MIRCdocument.