Difference between revisions of "NCBO-OOR Server-Side Customization"

From NCBO Wiki
Jump to navigation Jump to search
Line 83: Line 83:
 
</pre>
 
</pre>
  
The above configuration specifies that "ConceptServiceImpl" has a setter method named "setOntologyFormatHandlerMap" which accepts an injection of the map named "ontologyFormatHandlerMap" which includes both "OntologyLoadManagerProtegeImpl" and "OntologyLoadManagerLexGridImpl" as implementations of "OntologyLoadManager."
+
The above configuration specifies that "ConceptServiceImpl" has a setter method named "setOntologyFormatHandlerMap" which accepts an injection of the map named "ontologyFormatHandlerMap." This map is defined in a Spring configuration file (applicationContext-services.xml) and references both "OntologyLoadManagerProtegeImpl" and "OntologyLoadManagerLexGridImpl" as implementations of "OntologyLoadManager." In this case, the "FORMAT_HANDLER_PROTEGE" constant refers to "OntologyLoadManagerProtegeImpl" class and the "FORMAT_HANDLER_LEXGRID" constant refers to the "OntologyLoadManagerLexGridImpl" class. 
  
 
<pre>
 
<pre>
Line 91: Line 91:
 
<entry>
 
<entry>
 
<key>
 
<key>
<util:constant
+
<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_OWL" />
static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_OWL" />
 
 
</key>
 
</key>
<util:constant
+
<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_HANDLER_PROTEGE" />
static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_HANDLER_PROTEGE" />
 
 
</entry>
 
</entry>
 
<entry>
 
<entry>
 
<key>
 
<key>
<util:constant
+
<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_OWL_DL" />
static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_OWL_DL" />
 
 
</key>
 
</key>
<util:constant
+
<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_HANDLER_PROTEGE" />
static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_HANDLER_PROTEGE" />
 
 
</entry>
 
</entry>
 
<entry>
 
<entry>
 
<key>
 
<key>
<util:constant
+
<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_OWL_FULL" />
static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_OWL_FULL" />
 
 
</key>
 
</key>
<util:constant
+
<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_HANDLER_PROTEGE" />
static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_HANDLER_PROTEGE" />
 
 
</entry>
 
</entry>
 
<entry>
 
<entry>
 
<key>
 
<key>
<util:constant
+
<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_OWL_LITE" />
static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_OWL_LITE" />
 
 
</key>
 
</key>
<util:constant
+
<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_HANDLER_PROTEGE" />
static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_HANDLER_PROTEGE" />
 
 
</entry>
 
</entry>
 
<entry>
 
<entry>
 
<key>
 
<key>
<util:constant
+
<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_PROTEGE" />
static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_PROTEGE" />
 
 
</key>
 
</key>
<util:constant
+
<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_HANDLER_PROTEGE" />
static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_HANDLER_PROTEGE" />
 
 
</entry>
 
</entry>
 
<entry>
 
<entry>
 
<key>
 
<key>
<util:constant
+
<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_OBO" />
static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_OBO" />
 
 
</key>
 
</key>
<util:constant
+
<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_HANDLER_LEXGRID" />
static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_HANDLER_LEXGRID" />
 
 
</entry>
 
</entry>
 
<entry>
 
<entry>
 
<key>
 
<key>
<util:constant
+
<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_UMLS_RRF" />
static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_UMLS_RRF" />
 
 
</key>
 
</key>
<util:constant
+
<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_HANDLER_LEXGRID" />
static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_HANDLER_LEXGRID" />
 
 
</entry>
 
</entry>
 
<entry>
 
<entry>
 
<key>
 
<key>
<util:constant
+
<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_LEXGRID_XML" />
static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_LEXGRID_XML" />
 
 
</key>
 
</key>
<util:constant
+
<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_HANDLER_LEXGRID" />
static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_HANDLER_LEXGRID" />
 
 
</entry>
 
</entry>
 
</util:map>
 
</util:map>
 
</pre>
 
</pre>
 +
 +
The key for the map references the various ontology formats supports supported by BioPortal.  Thus, when a a request is made to load an ontology of a supported format, the "ontologyFormatHandlerMap" provides a flexible way to associate the ontology format type to appropriate loader upon at load time.
  
 
=Sample FileOntologyLoader Walk-Through=
 
=Sample FileOntologyLoader Walk-Through=

Revision as of 17:07, 11 February 2009

Introduction

NCBO-OOR provides server-side flexibility by leveraging the enterprise pattern of "Dependency Injection." This is accomplished by applying the Spring technology which enables a partner to insert any software implementation that abides to the NCBO-defined interfaces purely by configuration. In other words, a different implementation can be deployed without a recompile or rebuild of the entire NCBO-OOR code-base.

This first NCBO-OOR implemntation is based on the BioPortal architecture and code-base. Thus, the majority of the developer considerations for NCBO-OOR is generally applicable to the BioPortal (and vice-versa). The author will note differences where appropriate.

BioPortal Server-Side Pattern: Dependency Injection

The gist of dependency injection is that a seperate object, an assembler, populates the implementation of a defined interface that can be used by any consuming object that understands the interface. Spring implements a specific variation of this patterns called "Setter Injection." A significant number of BioPortal server-side capabilities heavily leverage this pattern. This approach enables these BioPortal capabilities to easily swap out different implementations. To learn more about this pattern in general, please see Martin Fowler's excellent exposition on this topic (http://martinfowler.com/articles/injection.html). The following sections elucidate a couple BioPortal-specific examples.

A Simple Example Walk-Through

This section walks-through a simple example where BioPortal leverages the Setter Injection model in the BioPortal Interface/Service Layer. In this scenario, "ConceptRestlet" accepts REST service invocation and delgates concept requests to an internal class named "ConceptServiceImpl." "ConceptRestlet" receives a hook to "ConceptServiceImpl" by having it injected by the Spring framework. "ConceptRestlet" is only aware of the "ConceptService" interface and has no direct reference to "ConceptServiceImpl."

To get my ConceptRestlet to accept the injection of the "ConceptServiceImpl" implementation, one first defines a setting method for that class:

public class ConceptRestlet...

 private ConceptService conceptService;
 public void setConceptService(ConceptService conceptService)
   this.conceptService = conceptService;
 }

One then specifies in the BioPortal Spring configuration file for the BioPortal Interface Layer ("applicationContext-rest.xml") the implementations to inject into ConceptRestlet. I've appended an excerpt from the configuration file:


	<bean id="conceptRestlet"
		class="org.ncbo.stanford.view.rest.restlet.concept.ConceptRestlet"
		parent="abstractBaseRestlet">
		<property name="conceptService">
			<ref bean="conceptService" />
		</property>
	</bean>

The above configuration specifies that "ConceptRestlet" has a setter method named "setConceptService" which accepts an injection of a bean implementation referenced by "conceptService." The following configuration (found in "applicationContext-services.xml") defines the "conceptService" bean to be "ConceptServiceImpl."

<bean id="conceptService"
		class="org.ncbo.stanford.service.concept.impl.ConceptServiceImpl">
		<property name="ncboOntologyVersionDAO">
			<ref bean="NcboOntologyVersionDAO" />
		</property>
		<property name="ontologyFormatHandlerMap">
			<ref local="ontologyFormatHandlerMap" />
		</property>
		<property name="ontologyRetrievalHandlerMap">
			<ref local="ontologyRetrievalHandlerMap" />
		</property>
</bean>

If a developer wanted to deploy a different "ConceptService" implementation, the person would simply need to copy the new compiled bean class file into the BioPortal deployment, change the Spring configuration file to point to this new implementation, and restart the application server.

BioPortal OntologyLoadManager Walk-Through

Now let's try digging into a more complex example of BioPortal Setter Injection model found in the Business Logic Layer. When new ontologies are loaded into BioPortal (either through the UI or through back end scheduled jobs), they are loaded either to two possible back-end repositories Protege or LexGrid. All OWL/Protege ontologies are loaded into Protege. All OBO/RRF (which are biomedical specific formats) are loaded into LexGrid. The following diagram presents this general architecture:

BP Ontology Load Architecture.jpg

In this scenario, we have the OntologyLoadManager interface which is consumed/used by the OntologyServiceImpl class. Since the OntologyLoadManager is an interface, it has no implementation.

To get my OntologyServiceImpl to accept the injection of the OntologyLoadManager implementations, I define a setting method for that class:

class OntologyServiceImpl...

   Map<String, OntologyRetrievalManager> ontologyRetrievalHandlerMap
   public void setOntologyLoadHandlerMap(Map<String, OntologyLoadManager> ontologyLoadHandlerMap) 
     this.finder = finder;
 }


One then specifies in the BioPortal Spring configuration file ("applicationContext-services.xml") the implementations to inject into OntologyServiceImpl. I've appended an excerpt from the configuration file:

	<bean id="conceptService"
	class="org.ncbo.stanford.service.concept.impl.ConceptServiceImpl">
		<property name="ncboOntologyVersionDAO">
			<ref bean="NcboOntologyVersionDAO" />
		</property>
		<property name="ontologyFormatHandlerMap">
			<ref local="ontologyFormatHandlerMap" />
		</property>
		<property name="ontologyRetrievalHandlerMap">
			<ref local="ontologyRetrievalHandlerMap" />
		</property>
	</bean>

The above configuration specifies that "ConceptServiceImpl" has a setter method named "setOntologyFormatHandlerMap" which accepts an injection of the map named "ontologyFormatHandlerMap." This map is defined in a Spring configuration file (applicationContext-services.xml) and references both "OntologyLoadManagerProtegeImpl" and "OntologyLoadManagerLexGridImpl" as implementations of "OntologyLoadManager." In this case, the "FORMAT_HANDLER_PROTEGE" constant refers to "OntologyLoadManagerProtegeImpl" class and the "FORMAT_HANDLER_LEXGRID" constant refers to the "OntologyLoadManagerLexGridImpl" class.

<!-- Ontology format handler map -->
	<util:map id="ontologyFormatHandlerMap"
		map-class="java.util.HashMap">
		<entry>
			<key>
				<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_OWL" />
			</key>
			<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_HANDLER_PROTEGE" />
		</entry>
		<entry>
			<key>
				<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_OWL_DL" />
			</key>
			<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_HANDLER_PROTEGE" />
		</entry>
		<entry>
			<key>
				<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_OWL_FULL" />
			</key>
			<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_HANDLER_PROTEGE" />
		</entry>
		<entry>
			<key>
				<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_OWL_LITE" />
			</key>
			<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_HANDLER_PROTEGE" />
		</entry>
		<entry>
			<key>
				<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_PROTEGE" />
			</key>
			<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_HANDLER_PROTEGE" />
		</entry>
		<entry>
			<key>
				<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_OBO" />
			</key>
			<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_HANDLER_LEXGRID" />
		</entry>
		<entry>
			<key>
				<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_UMLS_RRF" />
			</key>
			<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_HANDLER_LEXGRID" />
		</entry>
		<entry>
			<key>
				<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_LEXGRID_XML" />
			</key>
			<util:constant static-field="org.ncbo.stanford.util.constants.ApplicationConstants.FORMAT_HANDLER_LEXGRID" />
		</entry>
	</util:map>

The key for the map references the various ontology formats supports supported by BioPortal. Thus, when a a request is made to load an ontology of a supported format, the "ontologyFormatHandlerMap" provides a flexible way to associate the ontology format type to appropriate loader upon at load time.

Sample FileOntologyLoader Walk-Through