Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
$Id: ComponentContainerEmulator.java 59688 2009-04-03 23:45:02Z arwhyte@umich.edu $ Copyright (c) 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.osedu.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.sakaiproject.test;
 
 import java.io.File;
 import java.net.URL;
 import java.util.List;
 
Emulate the Sakai component environment set up by a running Tomcat container.
 
 public class ComponentContainerEmulator {
 	private static final Log log = LogFactory.getLog(ComponentContainerEmulator.class);
 	private static Object componentManager;

Configures the emulated component container to run integration tests.
 
 	public static void startComponentManagerForTest() {
 	}

Configures the emulated component container to run against the default deployment environment.
 
 	public static void startComponentManager() {
 	}
 	
 	public static void startComponentManager(String tomcatHomeString sakaiHome) {
 		if (.isDebugEnabled()) .debug("Starting the component manager; sakaiHome=" + sakaiHome + ", tomcatHome=" + tomcatHome);
 		if (isStarted()) {
 			if (.isInfoEnabled()) .info("Component manager already exists, so not starting after all");
 			return;
 		}
 
 		// Normalize file path.
 		char lastChar = tomcatHome.charAt(tomcatHome.length() - 1);
 		if ((lastChar != '/') && (lastChar != '\\')) {
 			tomcatHome += "/";
 		}
 		
 		// Set the system properties needed by the sakai component manager
 		if ((sakaiHome != null) && (sakaiHome.length() > 0)) {
 			System.setProperty("sakai.home"sakaiHome);
 		}
 		System.setProperty("sakai.components.root"tomcatHome + "components/");
 		
 		// Add the sakai jars to the current classpath.  Note:  We are limited to using the sun jvm now
 		URL[] sakaiUrls = getJarUrls(new String[] {tomcatHome + "common/endorsed/",
 				tomcatHome + "common/lib/"tomcatHome + "shared/lib/"});
 		try {
 			Method addMethod = URLClassLoader.class.getDeclaredMethod("addURL"new Class[] {URL.class});
 			addMethod.setAccessible(true);
 			for(int i=0; i<sakaiUrls.lengthi++) {
 				addMethod.invoke(appClassLoadernew Object[] {sakaiUrls[i]});
 			}
 			
 			Class<?> clazz = Class.forName("org.sakaiproject.component.cover.ComponentManager");
 			 = clazz.getDeclaredMethod("getInstance", (Class[])null).invoke((Object[])null, (Object[])null);
 		} catch (Exception e) {
 			// Wrap as runtime exception, since it's unlikely the caller will want to do
 			// anything but die.
 			if (e instanceof RuntimeException) {
 				throw (RuntimeException)e;
 			} else {
 				throw new RuntimeException(e);
 			}
 		}
		if (.isDebugEnabled()) .debug("Finished starting the component manager");
	}
	public static void stopComponentManager() {
		if (.isDebugEnabled()) .debug("Starting the component manager");
		if( != null) {
			try {
				Method closeMethod = .getClass().getMethod("close"new Class[0]);
				closeMethod.invoke(new Object[0]);
catch (Exception e) {
			}
else {
			if (.isInfoEnabled()) .info("Component manager already stopped");				
		}
	}
	public static boolean isStarted() {
		return ( != null);
	}

Returns:
a Spring ApplicationContext which can be specified as the parent for a client-loaded application context. It is NOT guaranteed to be useful for any other purpose.
		Object applicationContext = null;
		if ( != null) {
			try {
				Method getContextMethod = .getClass().getMethod("getApplicationContext"new Class[0]);
				applicationContext = getContextMethod.invoke(new Object[0]);
catch (Exception e) {
			}
		}
		return applicationContext;
	}

Convenience method to get a service bean from the Sakai component manager.

Parameters:
beanId The id of the service
Returns:
The service, or null if the ID is not registered
	public static final Object getService(String beanId) {
		try {
			Method getMethod = .getClass().getMethod("get"new Class[] {String.class});
			return getMethod.invoke(new Object[] {beanId});
catch (Exception e) {
			.error(ee);
			return null;
		}
	}

Convenience method to get a singleton service bean whose ID is the same as the input interface.

Parameters:
clazz the interface of the singleton service
Returns:
the implementing service
	public static final <T> T getService(Class<T> clazz) {
		String beanId = clazz.getName();
		return (T) getService(beanId);
	}

Work around Maven's inability to simply pass through selected system properties. By default, Surefire tests inherit no Java properties from the Maven process itself. Only property names explicitly set in the plug-in's "systemProperties" configuration will be available. So, for example, to pass the "sakai.home" property, you'd need something like this:
 <plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-surefire-plugin</artifactId>
   <configuration>
     <systemProperties>
       <property>
         <name>sakai.home</name>
         <value>${sakai.home}</value>
       </property>
     </systemProperties>
   </configuration>
 </plugin>
 
This doesn't work for optional Java properties, however. In the example above, if "sakai.home" is undefined, the Surefire plug-in will pass through a bogus string value of "${sakai.home}" rather than null. This utiltiy method checks for that condition.

Returns:
The Java system property value, or null if the value appears to be a Maven property reference itself.
	public static final String getPassthroughSystemProperty(String propertyName) {
		String value = System.getProperty(propertyName);
		if ((value != null) && value.matches("\\$\\{.+\\}")) {
			value = null;
		}
		return value;
	}

Point test.sakai.home at a directory in the test's resources area (typically "target/test-classes" for a Maven build) so that test-specific sakai.properties can be loaded.

Parameters:
pathPrefix the directory holding "sakai.properties" or "sakai-configuration.xml". an empty string indicates that the top of the classes directory should be used
	public static final void setTestSakaiHome(String pathPrefix) {
		URL sakaiHomeUrl = ComponentContainerEmulator.class.getClassLoader().getResource(pathPrefix);
		if (.isDebugEnabled()) .debug("sakaiHomeUrl=" + sakaiHomeUrl);
		if (sakaiHomeUrl != null) {
			System.setProperty("test.sakai.home"sakaiHomeUrl.getFile());
		}
	}

Looks for a Tomcat home.

Returns:
the value of the Java system property "maven.tomcat.home" or of the CATALINA_HOME environment variable
Throws:
java.lang.Exception
	public static final String findTomcatHome() {
		String tomcatHome = getPassthroughSystemProperty("maven.tomcat.home");
		if ( tomcatHome != null && tomcatHome.length() > 0 ) {
			if (.isDebugEnabled()) .debug("Using maven.tomcat.home: " + tomcatHome);
else {
			// For the sake of Eclipse, provide a non-Maven-ish approach.
			tomcatHome = System.getenv("CATALINA_HOME");
			if (.isDebugEnabled()) .debug("Using CATALINA_HOME: " + tomcatHome);
		}
		return tomcatHome;
	}

For backwards compatibility, checks for the Java system property "test.tomcat.home" or environment variable "TEST_CATALINA_HOME". If either is set, use it. If neither is set, go ahead and use the standard Tomcat home logic (which is the preferred approach).

Returns:
	public static final String findTestTomcatHome() {
		String tomcatHome = getPassthroughSystemProperty("test.tomcat.home");
		if ((tomcatHome != null) && (tomcatHome.length() > 0)) {
			if (.isDebugEnabled()) .debug("Using test.tomcat.home: " + tomcatHome);
else {
			// For the sake of Eclipse, provide a non-Maven-ish approach.
			tomcatHome = System.getenv("TEST_CATALINA_HOME");
			if ((tomcatHome != null) && (tomcatHome.length() > 0)) {
				if (.isDebugEnabled()) .debug("Using TEST_CATALINA_HOME: " + tomcatHome);
else {
				tomcatHome = findTomcatHome();
			}
		}
		return tomcatHome;
	}

Returns:
the value of the "test.sakai.home" Java system property, the value of the TEST_SAKAI_HOME environment variable, or null if neither is set.
	public static final String findTestSakaiHome() {
		String sakaiHome = getPassthroughSystemProperty("test.sakai.home");	// Can be null
		if ((sakaiHome != null) && (sakaiHome.length() > 0)) {
			if (.isDebugEnabled()) .debug("Using test.sakai.home: " + sakaiHome);
else {
			// For the sake of Eclipse, provide a non-Maven-ish approach.
			sakaiHome = System.getenv("TEST_SAKAI_HOME");
			if ((sakaiHome != null) && (sakaiHome.length() > 0)) {
				if (.isDebugEnabled()) .debug("Using TEST_SAKAI_HOME: " + sakaiHome);
			}
		}
		return sakaiHome;
	}

Builds an array of file URLs from a directory path.

Parameters:
dirPath
Returns:
Throws:
java.lang.Exception
	private static URL[] getJarUrls(String dirPath) {
		File dir = new File(dirPath);
		if (.isInfoEnabled()) .info("dirPath=" + dirPath + ", dir=" + dir);
		File[] jars = dir.listFiles(new FileFilter() {
			public boolean accept(File pathname) {
				if(pathname.getName().startsWith("xml-apis")) {
					return false;
				}
				return true;
			}
		});
		URL[] urls = new URL[jars.length];
		for(int i = 0; i < jars.lengthi++) {
			try {
				urls[i] = jars[i].toURL();
catch (MalformedURLException e) {
				.error(ee);
			}
		}
		return urls;
	}
	private static URL[] getJarUrls(String[] dirPaths) {
		List<URLjarList = new ArrayList<URL>();
		// Add all of the tomcat jars
		for(int i=0; i<dirPaths.lengthi++) {
			jarList.addAll(Arrays.asList(getJarUrls(dirPaths[i])));
		}
		URL[] urlArray = new URL[jarList.size()];
		jarList.toArray(urlArray);
		return urlArray;
	}
New to GrepCode? Check out our FAQ X