2008:Orion:Report: Difference between revisions
New page: CSI Academy Concerto Portal Development Mark Alan MacKinnon Gardiner Department of Electrical and Computer Engineering. University of Auckland. mgar059@ec.auckland.ac.nz Abstract Co... |
No edit summary |
||
Line 40: | Line 40: | ||
4. Code refactoring | 4. Code refactoring | ||
4.1 Concerto Portal | 4.1. Concerto Portal | ||
Refactoring is the process of taking code and making it easier to read and understand, without changing what it actually does. Concerto Portal is a relatively mature piece of software. Software technologies are rapidly evolving, and it is important for code to comply with modern standards and frameworks. Our task was to refactor the Concerto Portal code base so that it complied with modern coding practices. This would help improve the readability and understandability of the code, making it easier for developers to modify and maintain in the future. | Refactoring is the process of taking code and making it easier to read and understand, without changing what it actually does. Concerto Portal is a relatively mature piece of software. Software technologies are rapidly evolving, and it is important for code to comply with modern standards and frameworks. Our task was to refactor the Concerto Portal code base so that it complied with modern coding practices. This would help improve the readability and understandability of the code, making it easier for developers to modify and maintain in the future. | ||
With the introduction of java 5, new language features were introduced which make code easier to read and maintain. A few features which we used to refractor the Concerto code base were Generics, Enhanced for Loop, Autoboxing, and Annotations. | With the introduction of java 5, new language features were introduced which make code easier to read and maintain. A few features which we used to refractor the Concerto code base were Generics, Enhanced for Loop, Autoboxing, and Annotations. | ||
4.1.1 Generics | 4.1.1. Generics | ||
Of these, implementing generics was the most time consuming. There is frequent use of lists, sets and maps within the concerto source, which map the relationship of objects. Without generics it is hard to know what is in these lists. They could be a list of patients, or a list of messages. The danger is when a programmer tries to get a message from a list of patients, which can prevent Concerto from functioning correctly. Instead of having a raw list i.e. | Of these, implementing generics was the most time consuming. There is frequent use of lists, sets and maps within the concerto source, which map the relationship of objects. Without generics it is hard to know what is in these lists. They could be a list of patients, or a list of messages. The danger is when a programmer tries to get a message from a list of patients, which can prevent Concerto from functioning correctly. Instead of having a raw list i.e. | ||
List obj = getList(); | List obj = getList(); | ||
Line 52: | Line 52: | ||
As such, the compiler can check that list does in fact contain messages. This is also helpful to the programmer as they can easily see what is in the list, as well as remove the need for casting making the code easier to read and in cases removed the need for extra variables needed to cast the object before it was used. | As such, the compiler can check that list does in fact contain messages. This is also helpful to the programmer as they can easily see what is in the list, as well as remove the need for casting making the code easier to read and in cases removed the need for extra variables needed to cast the object before it was used. | ||
4.1.2 Enhanced for Loop | 4.1.2. Enhanced for Loop | ||
Enhanced for loops were used to reduce the need for iterators, which can be prone to errors and take up a large amount of code. Added to this Iterators can be hard to read and understand. For example: | Enhanced for loops were used to reduce the need for iterators, which can be prone to errors and take up a large amount of code. Added to this Iterators can be hard to read and understand. For example: | ||
**Hello I am an iterator. Does this variable suit me** | **Hello I am an iterator. Does this variable suit me** | ||
Line 59: | Line 59: | ||
This is much cleaner and easier to read. There were some cases however, where we were unable to implement a for-each loop. An example of this is where third party library’s were used which were also not generic. As we could not give a type to the elements coming back in the list, we were unable to for-each over an object which may not extend iterable. | This is much cleaner and easier to read. There were some cases however, where we were unable to implement a for-each loop. An example of this is where third party library’s were used which were also not generic. As we could not give a type to the elements coming back in the list, we were unable to for-each over an object which may not extend iterable. | ||
4.1.3 Autoboxing | 4.1.3. Autoboxing | ||
Autoboxing allowed us to remove redundant toObject(); methods. Before Java 5, primitive types could not be added to a collection. If you wanted to put primitives into a collection you hade to first convert them to their corresponding object class. For instance an ‘int’ would be converted to an ‘Integer’. With Java 5 this is no longer necessary, and as such previously needed toObject(); methods could be removed. | Autoboxing allowed us to remove redundant toObject(); methods. Before Java 5, primitive types could not be added to a collection. If you wanted to put primitives into a collection you hade to first convert them to their corresponding object class. For instance an ‘int’ would be converted to an ‘Integer’. With Java 5 this is no longer necessary, and as such previously needed toObject(); methods could be removed. | ||
4.1.4 Other changes | 4.1.4. Other changes | ||
Other minor changes we made to the Concerto code base include moving code such as the equals method, up the class definition hierarchy so that a single super class could implement equals which would then be inherited by all child classes. This removed some duplication of code, and means that if the equals method was to be changed, it would only have to be modified in one place and all the child classes would be changed too. Unfortunately, we found that due to the desired functionality of the equals method to only compare to objects of the same class, the equals methods did have to be reimplemented in many child classes. | Other minor changes we made to the Concerto code base include moving code such as the equals method, up the class definition hierarchy so that a single super class could implement equals which would then be inherited by all child classes. This removed some duplication of code, and means that if the equals method was to be changed, it would only have to be modified in one place and all the child classes would be changed too. Unfortunately, we found that due to the desired functionality of the equals method to only compare to objects of the same class, the equals methods did have to be reimplemented in many child classes. | ||
Annotations were automatically added where methods overrode super class methods, an example of this being the equals() method again. Another place changes had to be made were in the preDelete() methods. These methods ensure that when an object is deleted, for example a user on the system, every object belonging to that user is deleted before the user is deleted. | Annotations were automatically added where methods overrode super class methods, an example of this being the equals() method again. Another place changes had to be made were in the preDelete() methods. These methods ensure that when an object is deleted, for example a user on the system, every object belonging to that user is deleted before the user is deleted. | ||
4.2 Portal Interface Removal | 4.2. Portal Interface Removal | ||
After converting the Portal code to Java 5 standards where possible, the next task for us was to remove superfluous interfaces. Every object which was persisted to a database had an interface associated with it. These were identified by files ending in Bean.java. These interfaces exist so that it could be possible to switch persistence implementations. As future implementations are likely to be implemented using hibernate or a combination of plain Java objects combined with annotations. Either of these future approaches would mean that the interfaces are not essential, and are just unnecessarily cluttering up the code base. We removed these classes and changed the references to point to the concrete implementations. | After converting the Portal code to Java 5 standards where possible, the next task for us was to remove superfluous interfaces. Every object which was persisted to a database had an interface associated with it. These were identified by files ending in Bean.java. These interfaces exist so that it could be possible to switch persistence implementations. As future implementations are likely to be implemented using hibernate or a combination of plain Java objects combined with annotations. Either of these future approaches would mean that the interfaces are not essential, and are just unnecessarily cluttering up the code base. We removed these classes and changed the references to point to the concrete implementations. | ||
4.2.2 Automated changes | 4.2.2. Automated changes | ||
This task was made easier by the use of a perl script we made to search and replace text using a regular expression. We first made the script to update the copyright notices in all the Java source files. | This task was made easier by the use of a perl script we made to search and replace text using a regular expression. We first made the script to update the copyright notices in all the Java source files. | ||
5. Testing | 5. Testing | ||
5.1 Unit tests | 5.1. Unit tests | ||
The Concerto Portal has suites of tests written in JUnit. JUnit is a unit testing framework for Java. Once we had modified concerto to be largely generic, we ran the unit tests to ensure none of the functionality was broken. The unit tests were broken up into suites and each suite tested a package of the code base. | The Concerto Portal has suites of tests written in JUnit. JUnit is a unit testing framework for Java. Once we had modified concerto to be largely generic, we ran the unit tests to ensure none of the functionality was broken. The unit tests were broken up into suites and each suite tested a package of the code base. | ||
The tests were able to pick up a few problems including | The tests were able to pick up a few problems including | ||
Line 81: | Line 81: | ||
Some prototyping done with TestNG | Some prototyping done with TestNG | ||
5.2 Automated sanity tests. | 5.2. Automated sanity tests. | ||
Watfo framework in ruby | Watfo framework in ruby | ||
Xml because people didn’t like ruby. | Xml because people didn’t like ruby. | ||
Line 87: | Line 87: | ||
6. Tools and Frameworks | 6. Tools and Frameworks | ||
6.1 Java | 6.1. Java | ||
Concerto portal is written in Java. There are many good reasons for this. Java is interpreted and as a result can run on many different platforms. Concerto can run on Linux, Mac OS, Windows and others. The main benefit for Java is that there is a lot of support for it. Concerto uses many different open source frameworks to reduce the amount of development required. The Application Programming Interface for java is rich and includes libraries which provide functionality for programs running on an application server. Many tedious programming features such as memory management and garbage collection is handled natively by java, and there is plenty of support in the form of tools. | Concerto portal is written in Java. There are many good reasons for this. Java is interpreted and as a result can run on many different platforms. Concerto can run on Linux, Mac OS, Windows and others. The main benefit for Java is that there is a lot of support for it. Concerto uses many different open source frameworks to reduce the amount of development required. The Application Programming Interface for java is rich and includes libraries which provide functionality for programs running on an application server. Many tedious programming features such as memory management and garbage collection is handled natively by java, and there is plenty of support in the form of tools. | ||
6.2 Eclipse | 6.2. Eclipse | ||
Eclipse is an Integration Development Environment for java, which was originally created by IBM. It is now a free tool which is widely used and supported. | Eclipse is an Integration Development Environment for java, which was originally created by IBM. It is now a free tool which is widely used and supported. | ||
Muchose plugins | Muchose plugins | ||
Highlighted warnings and errors. Shortcuts made life easy. | Highlighted warnings and errors. Shortcuts made life easy. | ||
6.2.1 Ant | 6.2.1. Ant | ||
Ant is similar to the more common ‘make’ program is used to automate the build process for compiling Concerto. Concerto is made up of many different packages and libraries, having Ant manage these made building Concerto much simpler. Ant uses an XML file which contains a list of different actions which can be preformed. We used it to build the mapping files for objects to be persisted in a database, for cleaning the database, running unit tests, and for compiling Concerto. | Ant is similar to the more common ‘make’ program is used to automate the build process for compiling Concerto. Concerto is made up of many different packages and libraries, having Ant manage these made building Concerto much simpler. Ant uses an XML file which contains a list of different actions which can be preformed. We used it to build the mapping files for objects to be persisted in a database, for cleaning the database, running unit tests, and for compiling Concerto. | ||
6.2.2 Ivy | 6.2.2. Ivy | ||
Ivy is a dependency manager for java. Ivy works with Ant to resolver references to library’s. These dependencies are automatically resolved at build time. There is an eclipse plugin we used called IvyDE which generates libraries, and allows them to be resolved within eclipse. | Ivy is a dependency manager for java. Ivy works with Ant to resolver references to library’s. These dependencies are automatically resolved at build time. There is an eclipse plugin we used called IvyDE which generates libraries, and allows them to be resolved within eclipse. | ||
6.3 Hibernate | 6.3. Hibernate | ||
Hibernate is used within the Concerto Portal to simplify the process of taking Java Objects and storing them in a relational database. Within the database, tables correspond to an object and the columns correspond to the fields within that object. Hibernate allows the developer to forget about most of the programming needed to persist objects. SQL is automatically generated, hibernate can control the way objects are cached, and the synchronization between the database and memory. | Hibernate is used within the Concerto Portal to simplify the process of taking Java Objects and storing them in a relational database. Within the database, tables correspond to an object and the columns correspond to the fields within that object. Hibernate allows the developer to forget about most of the programming needed to persist objects. SQL is automatically generated, hibernate can control the way objects are cached, and the synchronization between the database and memory. | ||
6.4 JMX | 6.4. JMX | ||
Concerto is designed to work with multiple different systems. JMX allows administrators to connect to a running Concerto instance directly and manage the system. When concerto starts up it goes through various stages or operability. It may not completely start up if it does not have a fully set up database for example. JMX is used to allow a connection into concerto for managing it, if it has not successfully started. We used JMX to set up the database to get concerto into a runnable state. | Concerto is designed to work with multiple different systems. JMX allows administrators to connect to a running Concerto instance directly and manage the system. When concerto starts up it goes through various stages or operability. It may not completely start up if it does not have a fully set up database for example. JMX is used to allow a connection into concerto for managing it, if it has not successfully started. We used JMX to set up the database to get concerto into a runnable state. | ||
6.6 Subversion | 6.6. Subversion | ||
The Concerto Portal code base is stored and controlled by a subversion repository. This allowed us to synchronize the changes we were making in different areas of the code and work on it simultaneously. | The Concerto Portal code base is stored and controlled by a subversion repository. This allowed us to synchronize the changes we were making in different areas of the code and work on it simultaneously. | ||
A major benefit from this was the ability to access the repository from within eclipse. The Subclipse it allowed us to compare the changes we made with previous versions in the repository. These changes were highlighted and we could easily see if we had lost some code in the changes or revive methods we had removed. | A major benefit from this was the ability to access the repository from within eclipse. The Subclipse it allowed us to compare the changes we made with previous versions in the repository. These changes were highlighted and we could easily see if we had lost some code in the changes or revive methods we had removed. | ||
6.7 Orion Intranet | 6.7. Orion Intranet | ||
Within Orion there are widely used networking tools for communication and management available over the local intranet. | Within Orion there are widely used networking tools for communication and management available over the local intranet. | ||
6.7.1 Zimbra | 6.7.1. Zimbra | ||
Zimbra is open source email server software which caters for email access and meeting or document collaboration. | Zimbra is open source email server software which caters for email access and meeting or document collaboration. | ||
6.7.2 Confluence | 6.7.2. Confluence | ||
Same as the uni wiki we are using for CSI. | Same as the uni wiki we are using for CSI. | ||
First week, getting up to speed with the products. | First week, getting up to speed with the products. | ||
Line 120: | Line 120: | ||
Should have all information you need. | Should have all information you need. | ||
Latest updates | Latest updates | ||
6.7.3 Jira | 6.7.3. Jira | ||
Jira is a web interface which provides bug tracking, issue tracking and project management functionality. | Jira is a web interface which provides bug tracking, issue tracking and project management functionality. | ||
99. | 99. |
Revision as of 02:50, 18 February 2008
CSI Academy Concerto Portal Development
Mark Alan MacKinnon Gardiner
Department of Electrical and Computer Engineering. University of Auckland.
mgar059@ec.auckland.ac.nz
Abstract
Concerto Portal is a web-based system for integrating hospital information systems. Work was carried out for Orchestral Developments Limited through the Center for Software Innovation Academy. The work centred on code refactoring for the Concerto medical applications portal, and extended to test automation and prototyping of new unit testing frameworks. The work was carried out in a team of two students from the University of Auckland. Development was mainly done with Java, however work was done with perl, ruby, and XML.
1. Introduction
1.1. Background Orion Health produces a range of software solutions for the integration of medical applications. Concerto is a front for many of these programs, and provides a web interface that can be used by different rolls of hospital staff, to access information that is relevant to them, and provides functionality for sending messages and organizing patients. The concerto portal is written in Java and uses a wide range of frameworks and third part code libraries. In order to reduce development time and increase the understandability of their code, Orion Health has set their coding standards to conform to Suns Java 5 standards.
1.2. Objectives The main objective of this project was to bring the Concerto Portal inline with the Java 5 standards. This includes language features and enhancements such as generics, enhanced for loops, and autoboxing. The secondary objectives were to migrate the unit testing framework from JUnit to TestNG, and finish by helping the portal team with performance testing.
1.3. Overview
Refactoring of the Concerto Portal was archived with the aid of some common programming tools and a few scripts we wrote, using regular expressions in perl, for replacing parts of code. We introduced generic types, were it was possible to do so, and replaced many loops which used iterators, to instead use the enhanced for loop construct. We spent a lot of time ensuring the correctness of our code with the help of unit tests, automated sanity tests, and general smoke tests.
2. Project Management
This project was carried out under the guidance of the CSI Academy. This is a managed internship program which comprised of a team of two Students, Nicholas Irvine and myself, an industry mentor Simon Leigh, and an academic mentor Dr. Christof Lutteroth. The program involved weekly progress reports where progress was documented on a university ‘wiki’ page. There were weekly meetings where students from different teams attended seminars on industry and academic development.
Work on the Concerto Portal was carried out at Orion House in Mt Albert. The Auckland office is home to around 150 staff. There is an open plan work environment where most of the software development is done in two rooms on the ground floor. These rooms have around 80 people in one and 40 in the other. We were situated in the smaller of the two rooms and were amongst the ‘Package Integration and Testing’ and ‘Orders’ Teams. Each of us had a desk with a computer and network access. We were able to communicate with our industry mentor and developers in the other room by using Skype and an intranet.
The Portal team has a couple of weekly meetings, in which weekly progress and direction is discussed. We also attended meetings where we heard head a clinicians perspective of using Concerto Portal and information about how new frameworks would work with Concerto Portal.
3. Concerto Portal
Concerto Portal is one of a few software products produced by Orion Health, which make up a software solution for organizing information systems. Concerto Portal is a web-based application written in Java. Many hospitals have a range of programs and databases they use, from looking up patients x-rays, lab results, inpatients register and so on. Each of these programs may have to be run separately and requite a different login. Not only is this a hassle, but this can be slow and lives are literally at risk. Concerto Portal acts as a centralised interface for logging in and using these different systems.
With Concerto, clinicians or doctors can log in to the system once, and the authentication can be shared amongst the different medical applications that user has access too. Where in the past, a clinician may have had to search for a patient on one system to get a few details such as their medical history, and then switch to a different system to find their lab results, concerto can allow the clinician to search for the patient once and can switch between the patients documents and lab results without having to switch programs. Concerto also provides a consistent interface between these applications, which make finding information faster and more intuitive. Added to this, concerto even implements functionality for integration with emails and can be customized to the specific needs of each hospital and user.
4. Code refactoring 4.1. Concerto Portal Refactoring is the process of taking code and making it easier to read and understand, without changing what it actually does. Concerto Portal is a relatively mature piece of software. Software technologies are rapidly evolving, and it is important for code to comply with modern standards and frameworks. Our task was to refactor the Concerto Portal code base so that it complied with modern coding practices. This would help improve the readability and understandability of the code, making it easier for developers to modify and maintain in the future.
With the introduction of java 5, new language features were introduced which make code easier to read and maintain. A few features which we used to refractor the Concerto code base were Generics, Enhanced for Loop, Autoboxing, and Annotations.
4.1.1. Generics Of these, implementing generics was the most time consuming. There is frequent use of lists, sets and maps within the concerto source, which map the relationship of objects. Without generics it is hard to know what is in these lists. They could be a list of patients, or a list of messages. The danger is when a programmer tries to get a message from a list of patients, which can prevent Concerto from functioning correctly. Instead of having a raw list i.e. List obj = getList(); We could look through the code to find where the list is being created or added too and see what kind of objects are being put into the list. Once we have determined that the list contains only messages, we can add a tag to the list to notate what kind of objects are stored in the list i.e.
List<Message> obj = getList();
As such, the compiler can check that list does in fact contain messages. This is also helpful to the programmer as they can easily see what is in the list, as well as remove the need for casting making the code easier to read and in cases removed the need for extra variables needed to cast the object before it was used.
4.1.2. Enhanced for Loop Enhanced for loops were used to reduce the need for iterators, which can be prone to errors and take up a large amount of code. Added to this Iterators can be hard to read and understand. For example:
- Hello I am an iterator. Does this variable suit me**
With the introduction of for-each loops however, this can be rewritten as:
- The blue variable goes with the blue class and the red variable goes with the red class, its all so clear, my life is complete**
This is much cleaner and easier to read. There were some cases however, where we were unable to implement a for-each loop. An example of this is where third party library’s were used which were also not generic. As we could not give a type to the elements coming back in the list, we were unable to for-each over an object which may not extend iterable.
4.1.3. Autoboxing Autoboxing allowed us to remove redundant toObject(); methods. Before Java 5, primitive types could not be added to a collection. If you wanted to put primitives into a collection you hade to first convert them to their corresponding object class. For instance an ‘int’ would be converted to an ‘Integer’. With Java 5 this is no longer necessary, and as such previously needed toObject(); methods could be removed.
4.1.4. Other changes Other minor changes we made to the Concerto code base include moving code such as the equals method, up the class definition hierarchy so that a single super class could implement equals which would then be inherited by all child classes. This removed some duplication of code, and means that if the equals method was to be changed, it would only have to be modified in one place and all the child classes would be changed too. Unfortunately, we found that due to the desired functionality of the equals method to only compare to objects of the same class, the equals methods did have to be reimplemented in many child classes. Annotations were automatically added where methods overrode super class methods, an example of this being the equals() method again. Another place changes had to be made were in the preDelete() methods. These methods ensure that when an object is deleted, for example a user on the system, every object belonging to that user is deleted before the user is deleted.
4.2. Portal Interface Removal After converting the Portal code to Java 5 standards where possible, the next task for us was to remove superfluous interfaces. Every object which was persisted to a database had an interface associated with it. These were identified by files ending in Bean.java. These interfaces exist so that it could be possible to switch persistence implementations. As future implementations are likely to be implemented using hibernate or a combination of plain Java objects combined with annotations. Either of these future approaches would mean that the interfaces are not essential, and are just unnecessarily cluttering up the code base. We removed these classes and changed the references to point to the concrete implementations.
4.2.2. Automated changes This task was made easier by the use of a perl script we made to search and replace text using a regular expression. We first made the script to update the copyright notices in all the Java source files.
5. Testing 5.1. Unit tests The Concerto Portal has suites of tests written in JUnit. JUnit is a unit testing framework for Java. Once we had modified concerto to be largely generic, we ran the unit tests to ensure none of the functionality was broken. The unit tests were broken up into suites and each suite tested a package of the code base. The tests were able to pick up a few problems including Predeletes Class casts Missing resolve.
Some prototyping done with TestNG 5.2. Automated sanity tests. Watfo framework in ruby Xml because people didn’t like ruby.
6. Tools and Frameworks
6.1. Java
Concerto portal is written in Java. There are many good reasons for this. Java is interpreted and as a result can run on many different platforms. Concerto can run on Linux, Mac OS, Windows and others. The main benefit for Java is that there is a lot of support for it. Concerto uses many different open source frameworks to reduce the amount of development required. The Application Programming Interface for java is rich and includes libraries which provide functionality for programs running on an application server. Many tedious programming features such as memory management and garbage collection is handled natively by java, and there is plenty of support in the form of tools.
6.2. Eclipse Eclipse is an Integration Development Environment for java, which was originally created by IBM. It is now a free tool which is widely used and supported. Muchose plugins Highlighted warnings and errors. Shortcuts made life easy.
6.2.1. Ant Ant is similar to the more common ‘make’ program is used to automate the build process for compiling Concerto. Concerto is made up of many different packages and libraries, having Ant manage these made building Concerto much simpler. Ant uses an XML file which contains a list of different actions which can be preformed. We used it to build the mapping files for objects to be persisted in a database, for cleaning the database, running unit tests, and for compiling Concerto. 6.2.2. Ivy Ivy is a dependency manager for java. Ivy works with Ant to resolver references to library’s. These dependencies are automatically resolved at build time. There is an eclipse plugin we used called IvyDE which generates libraries, and allows them to be resolved within eclipse.
6.3. Hibernate Hibernate is used within the Concerto Portal to simplify the process of taking Java Objects and storing them in a relational database. Within the database, tables correspond to an object and the columns correspond to the fields within that object. Hibernate allows the developer to forget about most of the programming needed to persist objects. SQL is automatically generated, hibernate can control the way objects are cached, and the synchronization between the database and memory.
6.4. JMX Concerto is designed to work with multiple different systems. JMX allows administrators to connect to a running Concerto instance directly and manage the system. When concerto starts up it goes through various stages or operability. It may not completely start up if it does not have a fully set up database for example. JMX is used to allow a connection into concerto for managing it, if it has not successfully started. We used JMX to set up the database to get concerto into a runnable state.
6.6. Subversion The Concerto Portal code base is stored and controlled by a subversion repository. This allowed us to synchronize the changes we were making in different areas of the code and work on it simultaneously. A major benefit from this was the ability to access the repository from within eclipse. The Subclipse it allowed us to compare the changes we made with previous versions in the repository. These changes were highlighted and we could easily see if we had lost some code in the changes or revive methods we had removed.
6.7. Orion Intranet Within Orion there are widely used networking tools for communication and management available over the local intranet. 6.7.1. Zimbra Zimbra is open source email server software which caters for email access and meeting or document collaboration. 6.7.2. Confluence Same as the uni wiki we are using for CSI. First week, getting up to speed with the products. Install information. Should have all information you need. Latest updates 6.7.3. Jira Jira is a web interface which provides bug tracking, issue tracking and project management functionality. 99. http://www.cs.auckland.ac.nz/research/groups/ict/ict.php?module=home http://www.orionhealth.com/ http://en.wikipedia.org/wiki/Refactoring http://java.sun.com/j2se/1.5.0/docs/relnotes/features.html http://confluence/display/Conc/Test+Automation http://jira/browse/CPO-4971 http://en.wikipedia.org/wiki/JUnit http://en.wikipedia.org/wiki/Apache_Ant http://en.wikipedia.org/wiki/Apache_Ivy http://www.practicalembeddedjava.com/language/WhyUseJava.pdf http://www.zimbra.com/ http://en.wikipedia.org/wiki/Java_Platform%2C_Enterprise_Edition