/**********************************************************************************
* $URL: https://source.sakaiproject.org/svn/citations/trunk/citations-osid/xserver/src/java/org/sakaibrary/osid/loader/OsidLoader.java $
* $Id: OsidLoader.java 105079 2012-02-24 23:08:11Z ottenhoff@longsight.com $
***********************************************************************************
*
* Copyright (c) 2006, 2007, 2008 The Sakai Foundation
*
* Licensed under the Educational Community License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.opensource.org/licenses/ECL-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**********************************************************************************/
package org.sakaibrary.osid.loader;
/**
* OsidLoader loads a specific implementation of an Open Service Interface
* Definition (OSID) with its getManager method. The getManager method loads
* an instance of the OSID's org.osid.OsidManager, assigns the manager's OsidContext,
* assigns any configuration information, and returns the instance of the OSID
* implementation. This usage of the getManager method in the OsidLoader is
* how applications should bind a particular implementation to an OSID. The
* value of this approach is that an application can defer which specific OSID
* implementation is used until runtime. The specific implementation package
* name can then be part of the configuration information rather than being
* hard coded. Changing implementations is simplified with this approach.
*
* <p>
* As an example, in order to create a new Hierarchy, an application does not
* use the new operator. It uses the OsidLoader getManager method to get an
* instance of a class that implements HierarchyManager (a subclass of
* org.osid.OsidManager). The application uses the HierarchyManager instance to create
* the Hierarchy. It is the createHierarchy() method in some package (e.g.
* org.osid.hierarchy.impl.HierarchyManager) which uses the new operator on
* org.osid.hierarchy.impl.Hierarchy, casts it as
* org.osid.hierarchy.Hierarchy, and returns it to the application. This
* indirection offers the significant value of being able to change
* implementations in one spot with one modification, namely by using a
* implementation package name argument for the OsidLoader getManager method.
* </p>
*
* <p>
* Sample:
* <blockquote>
* org.osid.OsidContext myContext = new org.osid.OsidContext();<br/
* >String key = "myKey";<br/
* >myContext.assignContext(key, "I want to save this string as context");<br/
* >String whatWasMyContext = myContext.getContext(key);<br/
* >org.osid.hierarchy.HierarchyManager hierarchyManager =
* <blockquote>
* org.osid.OsidLoader.getManager("org.osid.hierarchy.HierarchyManager","org.osid.shared.impl",myContext,null);
* </blockquote>
* org.osid.hierarchy.Hierarchy myHierarchy =
* hierarchyManager.createHierarchy(...);<br/>
* </blockquote>
* </p>
*
* <p>
* A similar technique can be used for creating other objects. OSIDs that have
* org.osid.OsidManager implementations loaded by OsidLoader, will define an
* appropriate interface to create these objects.
* </p>
*
* <p>
* The arguments to OsidLoader.getManager method are the OSID org.osid.OsidManager
* interface name, the implementing package name, the OsidContext, and any
* additional configuration information.
* </p>
*
* <p>
* OSID Version: 2.0
* </p>
*
* <p>
* Licensed under the {@link org.osid.SidImplementationLicenseMIT MIT
* O.K.I. OSID Definition License}.
* </p>
*/
public class OsidLoader implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private static final org.apache.commons.logging.Log LOG =
org.apache.commons.logging.LogFactory.getLog(
"org.sakaibrary.osid.loader.OsidLoader" );
/**
* Returns an instance of the org.osid.OsidManager of the OSID specified by the OSID
* package org.osid.OsidManager interface name and the implementation package name.
* The implementation class name is constructed from the SID package
* Manager interface name. A configuration file name is constructed in a
* similar manner and if the file exists it is loaded into the
* implementation's org.osid.OsidManager's configuration.
*
* <p>
* Example: To load an implementation of the org.osid.Filing OSID
* implemented in a package "xyz", one would use:
* </p>
*
* <p>
* org.osid.filing.FilingManager fm =
* (org.osid.filing.FilingManager)org.osid.OsidLoader.getManager(
* </p>
*
* <p>
* "org.osid.filing.FilingManager" ,
* </p>
*
* <p>
* "xyz" ,
* </p>
*
* <p>
* new org.osid.OsidContext());
* </p>
*
* @param osidPackageManagerName osidPackageManagerName is a fully
* qualified org.osid.OsidManager interface name
* @param implPackageName implPackageName is a fully qualified
* implementation package name
* @param context
* @param additionalConfiguration
*
* @return org.osid.OsidManager
*
* @throws org.osid.OsidException An exception with one of the following
* messages defined in org.osid.OsidException: {@link
* org.osid.OsidException#OPERATION_FAILED OPERATION_FAILED},
* {@link org.osid.OsidException#NULL_ARGUMENT NULL_ARGUMENT},
* {@link org.osid.OsidException#VERSION_ERROR VERSION_ERROR},
* ={@link org.osid.OsidException#INTERFACE_NOT_FOUND
* INTERFACE_NOT_FOUND}, ={@link
* org.osid.OsidException#MANAGER_NOT_FOUND MANAGER_NOT_FOUND},
* ={@link org.osid.OsidException#MANAGER_INSTANTIATION_ERROR
* MANAGER_INSTANTIATION_ERROR}, ={@link
* org.osid.OsidException#ERROR_ASSIGNING_CONTEXT
* ERROR_ASSIGNING_CONTEXT}, ={@link
* org.osid.OsidException#ERROR_ASSIGNING_CONFIGURATION
* ERROR_ASSIGNING_CONFIGURATION}
*/
public static org.osid.OsidManager getManager(
String osidPackageManagerName, String implPackageName,
org.osid.OsidContext context,
java.util.Properties additionalConfiguration)
throws org.osid.OsidException {
try {
if ((null != context) && (null != osidPackageManagerName) &&
(null != implPackageName)) {
String osidInterfaceName = osidPackageManagerName;
String className = makeClassName(osidPackageManagerName);
String managerClassName = makeFullyQualifiedClassName(implPackageName,
className);
LOG.debug( "osid interface name: " + osidInterfaceName);
Class osidInterface = Class.forName(osidInterfaceName);
if (null != osidInterface) {
LOG.debug("osid manager class name: " + managerClassName);
Class managerClass = Class.forName(managerClassName);
if (null != managerClass) {
if (osidInterface.isAssignableFrom(managerClass)) {
org.osid.OsidManager manager = (org.osid.OsidManager) managerClass.newInstance();
if (null != manager) {
try {
manager.osidVersion_2_0();
} catch (Throwable ex) {
throw new org.osid.OsidException(org.osid.OsidException.VERSION_ERROR);
}
try {
manager.assignOsidContext(context);
} catch (Exception ex) {
throw new org.osid.OsidException(org.osid.OsidException.ERROR_ASSIGNING_CONTEXT);
}
try {
java.util.Properties configuration = getConfiguration(manager);
if (null == configuration) {
configuration = new java.util.Properties();
}
if (null != additionalConfiguration) {
java.util.Enumeration enumer = additionalConfiguration.propertyNames();
while (enumer.hasMoreElements()) {
java.io.Serializable key = (java.io.Serializable) enumer.nextElement();
if (null != key) {
java.io.Serializable value = (java.io.Serializable) additionalConfiguration.get(key);
if (null != value) {
configuration.put(key, value);
}
}
}
}
manager.assignConfiguration( configuration );
LOG.debug( "configuration has been assigned done." );
return manager;
} catch (Exception ex) {
throw new org.osid.OsidException(org.osid.OsidException.ERROR_ASSIGNING_CONFIGURATION);
}
}
throw new org.osid.OsidException(org.osid.OsidException.MANAGER_INSTANTIATION_ERROR);
}
throw new org.osid.OsidException(org.osid.OsidException.MANAGER_NOT_OSID_IMPLEMENTATION);
}
throw new org.osid.OsidException(org.osid.OsidException.MANAGER_NOT_FOUND);
}
throw new org.osid.OsidException(org.osid.OsidException.INTERFACE_NOT_FOUND);
}
throw new org.osid.OsidException(org.osid.OsidException.NULL_ARGUMENT);
} catch (org.osid.OsidException oex) {
LOG.error( oex.getMessage() );
throw new org.osid.OsidException(oex.getMessage());
} catch (java.lang.Throwable ex) {
LOG.error( ex.getMessage() );
throw new org.osid.OsidException(org.osid.OsidException.OPERATION_FAILED);
}
}
private static String makeClassName(String packageManagerName)
throws org.osid.OsidException {
String className = packageManagerName;
if (null != className) {
className = (className.endsWith(".")
? className.substring(0, className.length() - 1) : className);
int lastdot = className.lastIndexOf(".");
if (-1 != lastdot) {
className = className.substring(lastdot + 1);
}
}
return className;
}
private static String makeFullyQualifiedClassName(String packageName,
String className) throws org.osid.OsidException {
String cName = className;
if (null != packageName) {
String pName = (packageName.endsWith(".") ? packageName
: new String(packageName +
"."));
cName = pName + className;
}
return cName;
}
/******* Utility Methods For Sakai Implementations ********/
/**
* Get an InputStream for a particular file name - first check the sakai.home area and then
* revert to the classpath.
*
* This is a utility method used several places.
*/
public static java.io.InputStream getConfigStream(String fileName, Class curClass)
{
String dataFolder = "/data/";
String filePath = dataFolder + fileName;
try
{
java.io.File f = new java.io.File(filePath);
if (f.exists())
{
return new java.io.FileInputStream(f);
}
}
catch (Throwable t)
{
// Not found in the sakai.home area
}
if ( curClass == null ) return null;
// If there is a class context, load from the class context...
java.io.InputStream istream = null;
// Load from the class loader
istream = curClass.getClassLoader().getResourceAsStream(fileName);
if ( istream != null ) return istream;
// Load from the class relative
istream = curClass.getResourceAsStream(fileName);
if ( istream != null ) return istream;
// Loading from the class at the data root
istream = curClass.getResourceAsStream("/data/"+fileName);
return istream;
}
private static java.util.Properties getConfiguration(
org.osid.OsidManager manager) throws org.osid.OsidException {
java.util.Properties properties = null;
if (null != manager) {
Class managerClass = manager.getClass();
String propertyName = "default: RepositoryManager.properties";
try {
String managerClassName = managerClass.getName();
int index = managerClassName.lastIndexOf(".");
if (-1 != index) {
managerClassName = managerClassName.substring(index + 1);
}
// RepositoryManager.properties is built
propertyName = managerClassName + ".properties";
// read RepositoryManager.properties file
// java.io.InputStream is = new java.io.FileInputStream( "data/" +
// propertyName );
java.io.InputStream is = getConfigStream( propertyName, managerClass );
// RepositoryManager.properties is read and
// loaded into a java.util.Properties object
if (null != is) {
properties = new java.util.Properties();
properties.load(is);
}
LOG.debug( "Read osid manager properties from: " + propertyName );
} catch (Throwable ex) {
LOG.error( "Error reading " + propertyName + " property file --" +
ex.getMessage() );
}
}
return properties;
}
/**
* <p>
* MIT O.K.I. SID Definition License.
* </p>
*
* <p>
* <b>Copyright and license statement:</b>
* </p>
*
* <p>
* Copyright © 2003 Massachusetts Institute of Technology <or
* copyright holder>
* </p>
*
* <p>
* This work is being provided by the copyright holder(s) subject to
* the terms of the O.K.I. SID Definition License. By obtaining,
* using and/or copying this Work, you agree that you have read,
* understand, and will comply with the O.K.I. SID Definition
* License.
* </p>
*
* <p>
* THE WORK IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL MASSACHUSETTS INSTITUTE OF
* TECHNOLOGY, THE AUTHORS, OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE WORK OR THE USE OR OTHER DEALINGS IN THE WORK.
* </p>
*
* <p>
* <b>O.K.I. SID Definition License</b>
* </p>
*
* <p>
* This work (the “Work”), including any software,
* documents, or other items related to O.K.I. SID definitions, is
* being provided by the copyright holder(s) subject to the terms of
* the O.K.I. SID Definition License. By obtaining, using and/or
* copying this Work, you agree that you have read, understand, and
* will comply with the following terms and conditions of the
* O.K.I. SID Definition License:
* </p>
*
* <p>
* You may use, copy, and distribute unmodified versions of this Work
* for any purpose, without fee or royalty, provided that you include
* the following on ALL copies of the Work that you make or
* distribute:
* </p>
*
* <ul>
* <li>
* The full text of the O.K.I. SID Definition License in a location
* viewable to users of the redistributed Work.
* </li>
* </ul>
*
*
* <ul>
* <li>
* Any pre-existing intellectual property disclaimers, notices, or terms
* and conditions. If none exist, a short notice similar to the following
* should be used within the body of any redistributed Work:
* “Copyright © 2003 Massachusetts Institute of Technology. All
* Rights Reserved.”
* </li>
* </ul>
*
* <p>
* You may modify or create Derivatives of this Work only for your
* internal purposes. You shall not distribute or transfer any such
* Derivative of this Work to any location or any other third party.
* For purposes of this license, “Derivative” shall mean
* any derivative of the Work as defined in the United States
* Copyright Act of 1976, such as a translation or modification.
* </p>
*
* <p>
* THE WORK PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL MASSACHUSETTS INSTITUTE OF
* TECHNOLOGY, THE AUTHORS, OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE WORK OR THE USE OR OTHER DEALINGS IN THE WORK.
* </p>
*
* <p>
* The name and trademarks of copyright holder(s) and/or O.K.I. may
* NOT be used in advertising or publicity pertaining to the Work
* without specific, written prior permission. Title to copyright in
* the Work and any associated documentation will at all times remain
* with the copyright holders.
* </p>
*
* <p>
* The export of software employing encryption technology may require a
* specific license from the United States Government. It is the
* responsibility of any person or organization contemplating export
* to obtain such a license before exporting this Work.
* </p>
*/
}