Phase 1 Consumer Guide
Version Information
Some of the following information applies only to Sakaibrary work done for Sakai 2.3 (Sakaibrary's Phase 1). This work has progressed and will be included in Sakai 2.4 as the Citations Helper in the Resources Tool. Updated documentation to configure the Citations Helper is available at the Citations Helper page in Resources.
Description
The Sakaibrary Repository OSID Implementation (SROI) provides access to metasearch engines for searching an institution's licensed electronic databases for scholarly resources.
Contents
- Installation Notes (applies only to Sakai 2.3)
- Out-of-Band Agreements (valid for Sakai 2.4)
- Implementation Notes (valid for Sakai 2.4)
Installation Notes
At this time, due to changes that have been made to the Resources tool, Sakaibrary software can only be run from within a modified version of Sakai. This means that Sakaibrary software cannot neatly be dropped into an existing version of Sakai. We are currently working on this and hope to have this capability soon. If you have a test or pilot server in use and would like to import other experimental tools into our version of Sakai (with a modified Resources tool), you should be able to do so. Please contact Gaurav if you'd like to work together to do this.
Installation Walkthrough
Development Environment Setup
Below you will be given directions on what to do to get Sakaibrary up and running and not how to get your development environment (the tools you will need) set up. You will, however, be informed of the tools you will need for each step and linked to the Programmer's Cafe Working Group's Development Environment Setup Walkthrough documentation on setting up individual tools. If you do not find enough context information on the individual tool pages, try the Development Environment Setup Walkthrough main page.
1 Checkout the code
The Sakaibrary Project has its own branch within the 'contrib' section of Sakai's subversion repository. You will need to check out the most current tag to get our latest version.
What to do |
Tools you will need |
Notes |
---|---|---|
Checkout the latest Sakaibrary code (sakaibrary_phase-1-006) svn checkout https://source.sakaiproject.org/contrib/sakaibrary/branches/sakaibrary_phase-1-006/ This will checkout a full version of Sakai 2.3 along with Sakaibrary code and place it into a folder with the same name as the tag. |
Do not use Eclipse's Subversion plugin to checkout. Checkout will take a couple of minutes. |
2 Configure
There are a few configuration parameters that you must attend to.
What to do |
Tools you will need |
Notes |
---|---|---|
(for Ex Libris MetaLib) Edit RepositoryManager.properties <sakai_root>/xserver-osid/xserver-osid-impl/src/bundle/data/RepositoryManager.properties Follow the RepositoryManager.properties Configuration Walkthrough. |
MetaLib X-Server, MetaLib Management Interface |
For more details, view an example |
(for Sirsi SingleSearch) Edit searchsource.xml |
 |
 |
Edit sakai.properties <Tomcat_root>/sakai/sakai.properties Follow the sakai.properties Configuration Walkthrough. |
For more details, view an example |
3 Build and deploy
You can build and deploy Sakai as you normally would using Java, Maven, Tomcat and perhaps a database such as MySQL or Oracle.
What to do |
Tools you will need |
Notes |
---|---|---|
Configure Maven's build.properties /Users/gbhatnag/build.properties Make sure the following properties are defined: maven.repo.remote = http://source.sakaiproject.org/maven/, http://www.ibiblio.org/maven/public/html/maven/ maven.tomcat.home = /opt/apache-tomcat-5.5.17/ (your Tomcat install) maven.compile.source = 1.4 maven.compile.target = 1.4 maven.test.skip = true |
|
|
Build Sakai maven bld This will compile Sakai and make it ready to deploy. |
This will take a couple of minutes... |
|
Deploy Sakai maven dpl This will deploy Sakai to your Tomcat installation (defined in build.properties). |
This will take less time than building. |
4 Start Tomcat
You should now be able to start Tomcat and create Citation Lists using Sakaibrary software.
What to do |
Tools you will need |
Notes |
---|---|---|
Start Tomcat $CATALINA_HOME/bin/startup.sh |
Startup should take a minute or two - you can tail the log at: |
|
Verify Tomcat is running - you should see the generic Tomcat web page. |
 |
|
Verify Sakai is running - you should see the generic Sakai homepage. |
 |
|
Access the Citation List Editor and Search Library Resources Search Dialog
|
 |
 |
Out-of-Band Agreements
The Sakaibrary Repository OSID Implementation (SROI) is capable of conducting an asynchronous search of multiple databases. A number of out-of-band agreements (OBAs) need to be met by the Consumer to properly specify and manage such a search, as well as to utilize the results of such a search. For definitions of all SROI Types, please see the Repository Types page. Following is a summary of the major Types, Properties formats and criteria format needed to specify and manage a search using the SROI.
getAssetsBySearch()
The Repository method, getAssetsBySearch(), requires the following input parameters:
- java.io.Serializable searchCriteria
- org.osid.shared.Type searchType
- org.osid.shared.Properties searchProperties
searchType
The SROI defines and supports the sakaibrary / search / asynchMetasearch org.osid.shared.Type for searching. This search Type is used to initiate an asynchronous search of a metasearch engine and defines the other two fields (searchCriteria and searchProperties) associated with the getAssetsBySearch() method.
searchCriteria
The searchCriteria must be passed as a java.lang.String in CQL Format limited to the fields: keyword, title, author, subject, year and the relations: { = , and }.
Examples are:
- (keyword = clara+clairvoyant) and (keyword = lyrics)
- (((((keyword = clara+clairvoyant) and (keyword = lyrics)) and (title = open+road)) and (author = donovan)) and (subject = rock+and+roll+music)) and (year = 1970)
- ((((title = why+do+chimpanzees+hunt+and+share+meat) and (author = mitani)) and (author = watts)) and (subject = behavior)) and (subject = mating)
Classes from the org.sakaibrary.common.search.impl
package can be used to effectively parse user input and create proper CQL according to the above rules.
searchProperties
The SROI defines and supports the sakaibrary / properties / asynchMetasearch org.osid.shared.Type for properties. It is the responsibility of the Consumer to pass an object of type org.osid.shared.Properties to getAssetsBySearch() with the following properties:
- required properties are in red and starred
* guid
- A globally unique identifier. This is an alpha-numeric java.lang.String that uniquely identifies the specific user's search session.* baseUrl
- A java.lang.String base URL for the SROI's metasearch engine.* username
- A java.lang.String username used to login to the SROI's metasearch engine.* password
- A java.lang.String password used to login to the SROI's metasearch engine.sortBy
- A java.lang.String with one of the following values:- 'rank' - results are returned sorted by the metasearch engine's internal ranking algorithm.
- 'title' - results are returned sorted by title in ascending order (A-Z).
- 'author' - results are returned sorted by author's last name in ascending order (A-Z).
- 'year' - results are returned sorted by year in descending order (newer to older).
- 'database' - results are returned sorted by database in metasearch engine order.
- if undefined,
sortBy
defaults to 'rank'.
pageSize
- A java.lang.Integer indicating how many records to display per page. If undefined,pageSize
defaults to 10.startRecord
- A java.lang.Integer indicating which record to begin displaying results at. Records start at 1 and not 0. If undefined,startRecord
defaults to 1 (the first record).databaseIds
- A java.util.List of identifiers used to identify the databases to be searched by the metasearch engine. In Sakai 2.3, this field is not used.
A convenient way to pass an object of type org.osid.shared.Properties to getAssetsBySearch() with the above properties is to implement the org.osid.shared.Properties interface creating a class that wraps a java.util.HashMap as illustrated below.
getPropertiesByType( org.osid.shared.Type propertiesType )
The SROI defines the sakaibrary / properties / metasearchStatus Type for retrieving status information regarding an initiated asynchronous search. The Repository's getPropertiesByType() method can be used to retrieve search status information from the Repository. The org.osid.shared.Properties object of Type sakaibrary / properties / metasearchStatus returned has a unique key-value structure. Below is a table describing the structure of the Properties object:
key |
value |
---|---|
|
A java.lang.Integer representing the number of milliseconds the SROI recommends the Consumer wait before calling nextAsset() again. This number is only a suggestion and does not guarantee an Asset will be retrieved if the Consumer waits the indicated number of milliseconds. |
|
a java.util.ArrayList containing the |
|
A java.lang.String with status notification (searching, fetching, ready, error, timeout) for the entire search set. |
|
A java.lang.String with status details for the entire search set. |
|
A java.lang.Integer representing how many total records have been found for the entire search set. |
|
A java.lang.Integer representing how many records have been fetched for the entire search set. |
|
A java.lang.Integer representing how many records have been merged for the entire search set. |
|
A java.util.Map containing all of the above fields except for |
AssetIterator methods hasNextAsset() and nextAsset()
Access to individual Assets is encapsulated by the AssetIterator returned by Repository.getAssetsBySearch(). Calling hasNextAsset() returns a boolean indicating whether or not the end of the AssetIterator has been reached: true indicates there are more Assets in the AssetIterator, false indicates that there are no more Assets left. Calling nextAsset() returns an Asset, if it is available.
Due to the nature of an asynchronous search, there are a number of situations in which the hasNextAsset() and nextAsset() methods may not behave as described above. Consequently, the SROI provides special exception behavior for these two methods.
Method Behavior
The only Exception that may be thrown is an org.osid.repository.RepositoryException. This Exception is always thrown with a specific message indicating a specific problem that has occurred. These RepositoryException messages and the problems they indicate are described below.
hasNextAsset()
- returns true if the AssetIterator cursor has not yet reached the total number of records found.
- returns false if the AssetIterator cursor has reached the total number of records found.
- throws a RepositoryException with the SESSION_TIMED_OUT message if the session associated with this user's guid has been timed out by the metasearch engine.
- throws a RepositoryException with the METASEARCH_ERROR message if the search has failed due to a metasearch engine error.
- throws a RepositoryException with the OPERATION_FAILED message if resources the method needs cannot be gathered.
nextAsset()
- returns an Asset if the AssetIterator cursor has not yet reached the total number of records found and an Asset is readily available.
- throws a RepositoryException with the SESSION_TIMED_OUT message if the session associated with this user's guid has been timed out by the metasearch engine.
- throws a RepositoryException with the METASEARCH_ERROR message if the search has failed due to a metasearch engine error.
- throws a RepositoryException with the NO_MORE_ITERATOR_ELEMENTS message if the AssetIterator cursor has reached the total number of records found (equivalent to hasNextAsset() returning false).
- throws a RepositoryException with the ASSET_NOT_FETCHED message if the AssetIterator cursor has not yet reached the total number of records found (equivalent to hasNextAsset() returning true) but the current Asset has not yet been fetched.
- throws a RepositoryException with the OPERATION_FAILED message if resources the method needs cannot be gathered.
Implementation Notes
1. Get a RepositoryManager with org.sakaibrary.osid.repository.xserver or org.sakaibrary.osid.repository.web2 as the implementation package name:
org.osid.repository.RepositoryManager repositoryManager = OsidLoader.getManager( "org.osid.repository.RepositoryManager", "org.sakaibrary.osid.repository.xserver", new org.osid.OsidContext(), null );
2. Get the correct Repository Type from the RepositoryManager:
// find Repository Types org.osid.shared.TypeIterator typeIterator = repositoryManager.getRepositoryTypes(); // we are interested in "sakaibrary / repository / metasearch" type org.osid.shared.Type tempType; org.osid.shared.Type repositoryType = null; while( typeIterator.hasNextType() ) { tempType = typeIterator.nextType(); if( tempType != null && tempType.getAuthority() != null && tempType.getDomain() != null && tempType.getKeyword() != null ) { if( tempType.getAuthority().equals( "sakaibrary" ) && tempType.getDomain().equals( "repository" ) && tempType.getKeyword().equals( "metasearch" ) ) { repositoryType = tempType; } } }
3. Get Repositories of Type sakaibrary / repository / metasearch and find the selected Repository to search on (repository with 'repositoryName' has been selected):
org.osid.repository.RepositoryIterator repositoryIterator = repositoryManager.getRepositoriesByType( repositoryType ); while( repositoryIterator.hasNextRepository() ) { org.osid.repository.Repository repository = repositoryIterator.nextRepository(); if( repository.getDisplayName().equals( repositoryName ) ) { /* found a matching repository - do search */ // format search criteria to CQL // setup search properties // call getAssetsBySearch() // poll for results } }
4. Setup search properties and call getAssetsBySearch()
// setup search properties java.util.HashMap searchPropertiesMap = new java.util.HashMap(); searchPropertiesMap.put( "guid", "i9309we90rn203942309487kh0" ); searchPropertiesMap.put( "sortBy", "rank" ); searchPropertiesMap.put( "pageSize", new Integer( 10 ) ); searchPropertiesMap.put( "startRecord", new Integer( 1 ) ); searchPropertiesMap.put( "maxRecords", new Integer( 500 ) ); // ConsumerSearchProperties implements org.osid.shared.Properties and wraps a HashMap org.osid.shared.Properties searchProperties = new ConsumerSearchProperties( searchPropertiesMap ); // Conduct search org.osid.repository.AssetIterator assets = repository.getAssetsBySearch( criteria, searchType, searchProperties );
5. Poll for results.
org.osid.repository.Asset asset = null; try { while( assets.hasNextAsset() ) { try { asset = assets.nextAsset(); // Consumer gets the Asset - does something with it... } catch( RepositoryException re ) { if( re.getMessage().equals( org.sakaibrary.osid.repository.MetasearchException.SESSION_TIMED_OUT ) || re.getMessage().equals( org.sakaibrary.osid.repository.MetasearchException.METASEARCH_ERROR ) || re.getMessage().equals( org.osid.shared.SharedException.NO_MORE_ITERATOR_ELEMENTS ) || re.getMessage().equals( org.osid.OsidException.OPERATION_FAILED ) ) { // search is over, all assets that have been retrieved have been // optionally check searchStatus Properties for further details or information to present in UI break; } else if( re.getMessage.equals( org.sakaibrary.osid.repository.MetasearchException.ASSET_NOT_FETCHED ) ) { // need to wait some time and then try again Thread.sleep( ... ); } } // catch } // while } catch( RepositoryException re ) { if( re.getMessage().equals( org.sakaibrary.osid.repository.MetasearchException.SESSION_TIMED_OUT ) || re.getMessage().equals( org.sakaibrary.osid.repository.MetasearchException.METASEARCH_ERROR ) ) { // search is over, all assets that have been retrieved have been // optionally check searchStatus Properties for further details or information to present in UI } }