提交 ea68d343 编写于 作者: C Chris Beams

eliminated svn:externals in favor of localized copies of shared artifacts

上级 c442a581
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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.springframework.beans.factory.access;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.util.ClassUtils;
/**
* @author Colin Sampaleanu
* @author Chris Beams
*/
public class SingletonBeanFactoryLocatorTests {
@Test
public void testBasicFunctionality() {
SingletonBeanFactoryLocator facLoc = new SingletonBeanFactoryLocator(
"classpath*:" + ClassUtils.addResourcePathToPackagePath(getClass(), "ref1.xml"));
basicFunctionalityTest(facLoc);
}
/**
* Worker method so subclass can use it too.
*/
protected void basicFunctionalityTest(SingletonBeanFactoryLocator facLoc) {
BeanFactoryReference bfr = facLoc.useBeanFactory("a.qualified.name.of.some.sort");
BeanFactory fac = bfr.getFactory();
BeanFactoryReference bfr2 = facLoc.useBeanFactory("another.qualified.name");
fac = bfr2.getFactory();
// verify that the same instance is returned
TestBean tb = (TestBean) fac.getBean("beans1.bean1");
assertTrue(tb.getName().equals("beans1.bean1"));
tb.setName("was beans1.bean1");
BeanFactoryReference bfr3 = facLoc.useBeanFactory("another.qualified.name");
fac = bfr3.getFactory();
tb = (TestBean) fac.getBean("beans1.bean1");
assertTrue(tb.getName().equals("was beans1.bean1"));
BeanFactoryReference bfr4 = facLoc.useBeanFactory("a.qualified.name.which.is.an.alias");
fac = bfr4.getFactory();
tb = (TestBean) fac.getBean("beans1.bean1");
assertTrue(tb.getName().equals("was beans1.bean1"));
// Now verify that we can call release in any order.
// Unfortunately this doesn't validate complete release after the last one.
bfr2.release();
bfr3.release();
bfr.release();
bfr4.release();
}
/**
* This test can run multiple times, but due to static keyed lookup of the locators,
* 2nd and subsequent calls will actuall get back same locator instance. This is not
* an issue really, since the contained beanfactories will still be loaded and released.
*/
@Test
public void testGetInstance() {
// Try with and without 'classpath*:' prefix, and with 'classpath:' prefix.
BeanFactoryLocator facLoc = SingletonBeanFactoryLocator.getInstance(
ClassUtils.addResourcePathToPackagePath(getClass(), "ref1.xml"));
getInstanceTest1(facLoc);
facLoc = SingletonBeanFactoryLocator.getInstance(
"classpath*:/" + ClassUtils.addResourcePathToPackagePath(getClass(), "ref1.xml"));
getInstanceTest2(facLoc);
// This will actually get another locator instance, as the key is the resource name.
facLoc = SingletonBeanFactoryLocator.getInstance(
"classpath:" + ClassUtils.addResourcePathToPackagePath(getClass(), "ref1.xml"));
getInstanceTest3(facLoc);
}
/**
* Worker method so subclass can use it too
*/
protected void getInstanceTest1(BeanFactoryLocator facLoc) {
BeanFactoryReference bfr = facLoc.useBeanFactory("a.qualified.name.of.some.sort");
BeanFactory fac = bfr.getFactory();
BeanFactoryReference bfr2 = facLoc.useBeanFactory("another.qualified.name");
fac = bfr2.getFactory();
// verify that the same instance is returned
TestBean tb = (TestBean) fac.getBean("beans1.bean1");
assertTrue(tb.getName().equals("beans1.bean1"));
tb.setName("was beans1.bean1");
BeanFactoryReference bfr3 = facLoc.useBeanFactory("another.qualified.name");
fac = bfr3.getFactory();
tb = (TestBean) fac.getBean("beans1.bean1");
assertTrue(tb.getName().equals("was beans1.bean1"));
BeanFactoryReference bfr4 = facLoc.useBeanFactory("a.qualified.name.which.is.an.alias");
fac = bfr4.getFactory();
tb = (TestBean) fac.getBean("beans1.bean1");
assertTrue(tb.getName().equals("was beans1.bean1"));
bfr.release();
bfr3.release();
bfr2.release();
bfr4.release();
}
/**
* Worker method so subclass can use it too
*/
protected void getInstanceTest2(BeanFactoryLocator facLoc) {
BeanFactoryReference bfr;
BeanFactory fac;
BeanFactoryReference bfr2;
TestBean tb;
BeanFactoryReference bfr3;
BeanFactoryReference bfr4;
bfr = facLoc.useBeanFactory("a.qualified.name.of.some.sort");
fac = bfr.getFactory();
bfr2 = facLoc.useBeanFactory("another.qualified.name");
fac = bfr2.getFactory();
// verify that the same instance is returned
tb = (TestBean) fac.getBean("beans1.bean1");
assertTrue(tb.getName().equals("beans1.bean1"));
tb.setName("was beans1.bean1");
bfr3 = facLoc.useBeanFactory("another.qualified.name");
fac = bfr3.getFactory();
tb = (TestBean) fac.getBean("beans1.bean1");
assertTrue(tb.getName().equals("was beans1.bean1"));
bfr4 = facLoc.useBeanFactory("a.qualified.name.which.is.an.alias");
fac = bfr4.getFactory();
tb = (TestBean) fac.getBean("beans1.bean1");
assertTrue(tb.getName().equals("was beans1.bean1"));
bfr.release();
bfr2.release();
bfr4.release();
bfr3.release();
}
/**
* Worker method so subclass can use it too
*/
protected void getInstanceTest3(BeanFactoryLocator facLoc) {
BeanFactoryReference bfr;
BeanFactory fac;
BeanFactoryReference bfr2;
TestBean tb;
BeanFactoryReference bfr3;
BeanFactoryReference bfr4;
bfr = facLoc.useBeanFactory("a.qualified.name.of.some.sort");
fac = bfr.getFactory();
bfr2 = facLoc.useBeanFactory("another.qualified.name");
fac = bfr2.getFactory();
// verify that the same instance is returned
tb = (TestBean) fac.getBean("beans1.bean1");
assertTrue(tb.getName().equals("beans1.bean1"));
tb.setName("was beans1.bean1");
bfr3 = facLoc.useBeanFactory("another.qualified.name");
fac = bfr3.getFactory();
tb = (TestBean) fac.getBean("beans1.bean1");
assertTrue(tb.getName().equals("was beans1.bean1"));
bfr4 = facLoc.useBeanFactory("a.qualified.name.which.is.an.alias");
fac = bfr4.getFactory();
tb = (TestBean) fac.getBean("beans1.bean1");
assertTrue(tb.getName().equals("was beans1.bean1"));
bfr4.release();
bfr3.release();
bfr2.release();
bfr.release();
}
}
/*
* Copyright 2002-2005 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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.springframework.beans.factory.access;
import java.util.List;
/**
* Scrap bean for use in tests.
*
* @author Colin Sampaleanu
*/
public class TestBean {
private String name;
private List list;
private Object objRef;
/**
* @return Returns the name.
*/
public String getName() {
return name;
}
/**
* @param name The name to set.
*/
public void setName(String name) {
this.name = name;
}
/**
* @return Returns the list.
*/
public List getList() {
return list;
}
/**
* @param list The list to set.
*/
public void setList(List list) {
this.list = list;
}
/**
* @return Returns the object.
*/
public Object getObjRef() {
return objRef;
}
/**
* @param object The object to set.
*/
public void setObjRef(Object object) {
this.objRef = object;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!-- $Id: beans1.xml,v 1.3 2006/08/20 19:08:40 jhoeller Exp $ -->
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="beans1.bean1" class="org.springframework.beans.factory.access.TestBean">
<property name="name"><value>beans1.bean1</value></property>
</bean>
<bean id="beans1.bean2" class="org.springframework.beans.factory.access.TestBean">
<property name="name"><value>bean2</value></property>
<property name="objRef"><ref bean="beans1.bean2"/></property>
</bean>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<!-- $Id: beans2.xml,v 1.3 2006/08/20 19:08:40 jhoeller Exp $ -->
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="beans2.bean1" class="org.springframework.beans.factory.access.TestBean">
<property name="name"><value>beans2.bean1</value></property>
</bean>
<bean id="beans2.bean2" class="org.springframework.beans.factory.access.TestBean">
<property name="name"><value>beans2.bean2</value></property>
<property name="objRef"><ref bean="beans1.bean1"/></property>
</bean>
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<!-- We are only using one definition file for the purposes of this test, since we do not have multiple
classloaders available in the environment to allow combining multiple files of the same name, but
of course the contents within could be spread out across multiple files of the same name withing
different jars -->
<beans>
<!-- this definition could be inside one beanRefFactory.xml file -->
<bean id="a.qualified.name.of.some.sort"
class="org.springframework.beans.factory.xml.XmlBeanFactory">
<constructor-arg value="org/springframework/beans/factory/access/beans1.xml"/>
</bean>
<!-- while the following two could be inside another, also on the classpath,
perhaps coming from another component jar -->
<bean id="another.qualified.name"
class="org.springframework.beans.factory.xml.XmlBeanFactory">
<constructor-arg value="org/springframework/beans/factory/access/beans1.xml"/>
<constructor-arg ref="a.qualified.name.of.some.sort"/> <!-- parent bean factory -->
</bean>
<alias name="another.qualified.name" alias="a.qualified.name.which.is.an.alias"/>
</beans>
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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.springframework.mock.jndi;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.naming.NamingException;
import org.springframework.core.CollectionFactory;
import org.springframework.jndi.JndiTemplate;
/**
* Simple extension of the JndiTemplate class that always returns
* a given object. Very useful for testing. Effectively a mock object.
*
* @author Rod Johnson
* @author Juergen Hoeller
*/
public class ExpectedLookupTemplate extends JndiTemplate {
private final Map<String, Object> jndiObjects = new ConcurrentHashMap<String, Object>();
/**
* Construct a new JndiTemplate that will always return given objects
* for given names. To be populated through <code>addObject</code> calls.
* @see #addObject(String, Object)
*/
public ExpectedLookupTemplate() {
}
/**
* Construct a new JndiTemplate that will always return the
* given object, but honour only requests for the given name.
* @param name the name the client is expected to look up
* @param object the object that will be returned
*/
public ExpectedLookupTemplate(String name, Object object) {
addObject(name, object);
}
/**
* Add the given object to the list of JNDI objects that this
* template will expose.
* @param name the name the client is expected to look up
* @param object the object that will be returned
*/
public void addObject(String name, Object object) {
this.jndiObjects.put(name, object);
}
/**
* If the name is the expected name specified in the constructor,
* return the object provided in the constructor. If the name is
* unexpected, a respective NamingException gets thrown.
*/
public Object lookup(String name) throws NamingException {
Object object = this.jndiObjects.get(name);
if (object == null) {
throw new NamingException("Unexpected JNDI name '" + name + "': expecting " + this.jndiObjects.keySet());
}
return object;
}
}
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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.springframework.mock.jndi;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import javax.naming.Binding;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NameClassPair;
import javax.naming.NameNotFoundException;
import javax.naming.NameParser;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.OperationNotSupportedException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.StringUtils;
/**
* Simple implementation of a JNDI naming context.
* Only supports binding plain Objects to String names.
* Mainly for test environments, but also usable for standalone applications.
*
* <p>This class is not intended for direct usage by applications, although it
* can be used for example to override JndiTemplate's <code>createInitialContext</code>
* method in unit tests. Typically, SimpleNamingContextBuilder will be used to
* set up a JVM-level JNDI environment.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @see org.springframework.mock.jndi.SimpleNamingContextBuilder
* @see org.springframework.jndi.JndiTemplate#createInitialContext
*/
public class SimpleNamingContext implements Context {
private final Log logger = LogFactory.getLog(getClass());
private final String root;
private final Hashtable<String, Object> boundObjects;
private final Hashtable<String, Object> environment = new Hashtable<String, Object>();
/**
* Create a new naming context.
*/
public SimpleNamingContext() {
this("");
}
/**
* Create a new naming context with the given naming root.
*/
public SimpleNamingContext(String root) {
this.root = root;
this.boundObjects = new Hashtable<String, Object>();
}
/**
* Create a new naming context with the given naming root,
* the given name/object map, and the JNDI environment entries.
*/
public SimpleNamingContext(String root, Hashtable<String, Object> boundObjects, Hashtable<String, Object> env) {
this.root = root;
this.boundObjects = boundObjects;
if (env != null) {
this.environment.putAll(env);
}
}
// Actual implementations of Context methods follow
public NamingEnumeration<NameClassPair> list(String root) throws NamingException {
if (logger.isDebugEnabled()) {
logger.debug("Listing name/class pairs under [" + root + "]");
}
return new NameClassPairEnumeration(this, root);
}
public NamingEnumeration<Binding> listBindings(String root) throws NamingException {
if (logger.isDebugEnabled()) {
logger.debug("Listing bindings under [" + root + "]");
}
return new BindingEnumeration(this, root);
}
/**
* Look up the object with the given name.
* <p>Note: Not intended for direct use by applications.
* Will be used by any standard InitialContext JNDI lookups.
* @throws javax.naming.NameNotFoundException if the object could not be found
*/
public Object lookup(String lookupName) throws NameNotFoundException {
String name = this.root + lookupName;
if (logger.isDebugEnabled()) {
logger.debug("Static JNDI lookup: [" + name + "]");
}
if ("".equals(name)) {
return new SimpleNamingContext(this.root, this.boundObjects, this.environment);
}
Object found = this.boundObjects.get(name);
if (found == null) {
if (!name.endsWith("/")) {
name = name + "/";
}
for (String boundName : this.boundObjects.keySet()) {
if (boundName.startsWith(name)) {
return new SimpleNamingContext(name, this.boundObjects, this.environment);
}
}
throw new NameNotFoundException(
"Name [" + this.root + lookupName + "] not bound; " + this.boundObjects.size() + " bindings: [" +
StringUtils.collectionToDelimitedString(this.boundObjects.keySet(), ",") + "]");
}
return found;
}
public Object lookupLink(String name) throws NameNotFoundException {
return lookup(name);
}
/**
* Bind the given object to the given name.
* Note: Not intended for direct use by applications
* if setting up a JVM-level JNDI environment.
* Use SimpleNamingContextBuilder to set up JNDI bindings then.
* @see org.springframework.mock.jndi.SimpleNamingContextBuilder#bind
*/
public void bind(String name, Object obj) {
if (logger.isInfoEnabled()) {
logger.info("Static JNDI binding: [" + this.root + name + "] = [" + obj + "]");
}
this.boundObjects.put(this.root + name, obj);
}
public void unbind(String name) {
if (logger.isInfoEnabled()) {
logger.info("Static JNDI remove: [" + this.root + name + "]");
}
this.boundObjects.remove(this.root + name);
}
public void rebind(String name, Object obj) {
bind(name, obj);
}
public void rename(String oldName, String newName) throws NameNotFoundException {
Object obj = lookup(oldName);
unbind(oldName);
bind(newName, obj);
}
public Context createSubcontext(String name) {
String subcontextName = this.root + name;
if (!subcontextName.endsWith("/")) {
subcontextName += "/";
}
Context subcontext = new SimpleNamingContext(subcontextName, this.boundObjects, this.environment);
bind(name, subcontext);
return subcontext;
}
public void destroySubcontext(String name) {
unbind(name);
}
public String composeName(String name, String prefix) {
return prefix + name;
}
public Hashtable<String, Object> getEnvironment() {
return this.environment;
}
public Object addToEnvironment(String propName, Object propVal) {
return this.environment.put(propName, propVal);
}
public Object removeFromEnvironment(String propName) {
return this.environment.remove(propName);
}
public void close() {
}
// Unsupported methods follow: no support for javax.naming.Name
public NamingEnumeration<NameClassPair> list(Name name) throws NamingException {
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
}
public NamingEnumeration<Binding> listBindings(Name name) throws NamingException {
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
}
public Object lookup(Name name) throws NamingException {
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
}
public Object lookupLink(Name name) throws NamingException {
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
}
public void bind(Name name, Object obj) throws NamingException {
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
}
public void unbind(Name name) throws NamingException {
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
}
public void rebind(Name name, Object obj) throws NamingException {
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
}
public void rename(Name oldName, Name newName) throws NamingException {
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
}
public Context createSubcontext(Name name) throws NamingException {
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
}
public void destroySubcontext(Name name) throws NamingException {
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
}
public String getNameInNamespace() throws NamingException {
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
}
public NameParser getNameParser(Name name) throws NamingException {
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
}
public NameParser getNameParser(String name) throws NamingException {
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
}
public Name composeName(Name name, Name prefix) throws NamingException {
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
}
private static abstract class AbstractNamingEnumeration<T> implements NamingEnumeration<T> {
private Iterator<T> iterator;
private AbstractNamingEnumeration(SimpleNamingContext context, String proot) throws NamingException {
if (!"".equals(proot) && !proot.endsWith("/")) {
proot = proot + "/";
}
String root = context.root + proot;
Map<String, T> contents = new HashMap<String, T>();
for (String boundName : context.boundObjects.keySet()) {
if (boundName.startsWith(root)) {
int startIndex = root.length();
int endIndex = boundName.indexOf('/', startIndex);
String strippedName =
(endIndex != -1 ? boundName.substring(startIndex, endIndex) : boundName.substring(startIndex));
if (!contents.containsKey(strippedName)) {
try {
contents.put(strippedName, createObject(strippedName, context.lookup(proot + strippedName)));
}
catch (NameNotFoundException ex) {
// cannot happen
}
}
}
}
if (contents.size() == 0) {
throw new NamingException("Invalid root: [" + context.root + proot + "]");
}
this.iterator = contents.values().iterator();
}
protected abstract T createObject(String strippedName, Object obj);
public boolean hasMore() {
return this.iterator.hasNext();
}
public T next() {
return this.iterator.next();
}
public boolean hasMoreElements() {
return this.iterator.hasNext();
}
public T nextElement() {
return this.iterator.next();
}
public void close() {
}
}
private static class NameClassPairEnumeration extends AbstractNamingEnumeration<NameClassPair> {
private NameClassPairEnumeration(SimpleNamingContext context, String root) throws NamingException {
super(context, root);
}
protected NameClassPair createObject(String strippedName, Object obj) {
return new NameClassPair(strippedName, obj.getClass().getName());
}
}
private static class BindingEnumeration extends AbstractNamingEnumeration<Binding> {
private BindingEnumeration(SimpleNamingContext context, String root) throws NamingException {
super(context, root);
}
protected Binding createObject(String strippedName, Object obj) {
return new Binding(strippedName, obj);
}
}
}
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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.springframework.mock.jndi;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.spi.InitialContextFactory;
import javax.naming.spi.InitialContextFactoryBuilder;
import javax.naming.spi.NamingManager;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.ClassUtils;
/**
* Simple implementation of a JNDI naming context builder.
*
* <p>Mainly targeted at test environments, where each test case can
* configure JNDI appropriately, so that <code>new InitialContext()</code>
* will expose the required objects. Also usable for standalone applications,
* e.g. for binding a JDBC DataSource to a well-known JNDI location, to be
* able to use traditional J2EE data access code outside of a J2EE container.
*
* <p>There are various choices for DataSource implementations:
* <ul>
* <li>SingleConnectionDataSource (using the same Connection for all getConnection calls);
* <li>DriverManagerDataSource (creating a new Connection on each getConnection call);
* <li>Apache's Jakarta Commons DBCP offers BasicDataSource (a real pool).
* </ul>
*
* <p>Typical usage in bootstrap code:
*
* <pre class="code">
* SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
* DataSource ds = new DriverManagerDataSource(...);
* builder.bind("java:comp/env/jdbc/myds", ds);
* builder.activate();</pre>
*
* Note that it's impossible to activate multiple builders within the same JVM,
* due to JNDI restrictions. Thus to configure a fresh builder repeatedly, use
* the following code to get a reference to either an already activated builder
* or a newly activated one:
*
* <pre class="code">
* SimpleNamingContextBuilder builder = SimpleNamingContextBuilder.emptyActivatedContextBuilder();
* DataSource ds = new DriverManagerDataSource(...);
* builder.bind("java:comp/env/jdbc/myds", ds);</pre>
*
* Note that you <i>should not</i> call <code>activate()</code> on a builder from
* this factory method, as there will already be an activated one in any case.
*
* <p>An instance of this class is only necessary at setup time.
* An application does not need to keep a reference to it after activation.
*
* @author Juergen Hoeller
* @author Rod Johnson
* @see #emptyActivatedContextBuilder()
* @see #bind(String, Object)
* @see #activate()
* @see org.springframework.mock.jndi.SimpleNamingContext
* @see org.springframework.jdbc.datasource.SingleConnectionDataSource
* @see org.springframework.jdbc.datasource.DriverManagerDataSource
* @see org.apache.commons.dbcp.BasicDataSource
*/
public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder {
/** An instance of this class bound to JNDI */
private static volatile SimpleNamingContextBuilder activated;
private static boolean initialized = false;
private static final Object initializationLock = new Object();
/**
* Checks if a SimpleNamingContextBuilder is active.
* @return the current SimpleNamingContextBuilder instance,
* or <code>null</code> if none
*/
public static SimpleNamingContextBuilder getCurrentContextBuilder() {
return activated;
}
/**
* If no SimpleNamingContextBuilder is already configuring JNDI,
* create and activate one. Otherwise take the existing activate
* SimpleNamingContextBuilder, clear it and return it.
* <p>This is mainly intended for test suites that want to
* reinitialize JNDI bindings from scratch repeatedly.
* @return an empty SimpleNamingContextBuilder that can be used
* to control JNDI bindings
*/
public static SimpleNamingContextBuilder emptyActivatedContextBuilder() throws NamingException {
if (activated != null) {
// Clear already activated context builder.
activated.clear();
}
else {
// Create and activate new context builder.
SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
// The activate() call will cause an assigment to the activated variable.
builder.activate();
}
return activated;
}
private final Log logger = LogFactory.getLog(getClass());
private final Hashtable boundObjects = new Hashtable();
/**
* Register the context builder by registering it with the JNDI NamingManager.
* Note that once this has been done, <code>new InitialContext()</code> will always
* return a context from this factory. Use the <code>emptyActivatedContextBuilder()</code>
* static method to get an empty context (for example, in test methods).
* @throws IllegalStateException if there's already a naming context builder
* registered with the JNDI NamingManager
*/
public void activate() throws IllegalStateException, NamingException {
logger.info("Activating simple JNDI environment");
synchronized (initializationLock) {
if (!initialized) {
if (NamingManager.hasInitialContextFactoryBuilder()) {
throw new IllegalStateException(
"Cannot activate SimpleNamingContextBuilder: there is already a JNDI provider registered. " +
"Note that JNDI is a JVM-wide service, shared at the JVM system class loader level, " +
"with no reset option. As a consequence, a JNDI provider must only be registered once per JVM.");
}
NamingManager.setInitialContextFactoryBuilder(this);
initialized = true;
}
}
activated = this;
}
/**
* Temporarily deactivate this context builder. It will remain registered with
* the JNDI NamingManager but will delegate to the standard JNDI InitialContextFactory
* (if configured) instead of exposing its own bound objects.
* <p>Call <code>activate()</code> again in order to expose this contexz builder's own
* bound objects again. Such activate/deactivate sequences can be applied any number
* of times (e.g. within a larger integration test suite running in the same VM).
* @see #activate()
*/
public void deactivate() {
logger.info("Deactivating simple JNDI environment");
activated = null;
}
/**
* Clear all bindings in this context builder, while keeping it active.
*/
public void clear() {
this.boundObjects.clear();
}
/**
* Bind the given object under the given name, for all naming contexts
* that this context builder will generate.
* @param name the JNDI name of the object (e.g. "java:comp/env/jdbc/myds")
* @param obj the object to bind (e.g. a DataSource implementation)
*/
public void bind(String name, Object obj) {
if (logger.isInfoEnabled()) {
logger.info("Static JNDI binding: [" + name + "] = [" + obj + "]");
}
this.boundObjects.put(name, obj);
}
/**
* Simple InitialContextFactoryBuilder implementation,
* creating a new SimpleNamingContext instance.
* @see SimpleNamingContext
*/
public InitialContextFactory createInitialContextFactory(Hashtable environment) {
if (activated == null && environment != null) {
Object icf = environment.get(Context.INITIAL_CONTEXT_FACTORY);
if (icf != null) {
Class icfClass = null;
if (icf instanceof Class) {
icfClass = (Class) icf;
}
else if (icf instanceof String) {
icfClass = ClassUtils.resolveClassName((String) icf, getClass().getClassLoader());
}
else {
throw new IllegalArgumentException("Invalid value type for environment key [" +
Context.INITIAL_CONTEXT_FACTORY + "]: " + icf.getClass().getName());
}
if (!InitialContextFactory.class.isAssignableFrom(icfClass)) {
throw new IllegalArgumentException(
"Specified class does not implement [" + InitialContextFactory.class.getName() + "]: " + icf);
}
try {
return (InitialContextFactory) icfClass.newInstance();
}
catch (Throwable ex) {
IllegalStateException ise =
new IllegalStateException("Cannot instantiate specified InitialContextFactory: " + icf);
ise.initCause(ex);
throw ise;
}
}
}
// Default case...
return new InitialContextFactory() {
public Context getInitialContext(Hashtable environment) {
return new SimpleNamingContext("", boundObjects, environment);
}
};
}
}
<html>
<body>
The simplest implementation of the JNDI SPI that could possibly work.
<p>Useful for setting up a simple JNDI environment for test suites
or standalone applications. If e.g. JDBC DataSources get bound to the
same JNDI names as within a J2EE container, both application code and
configuration can me reused without changes.
</body>
</html>
/**
*
*/
package example.aspects;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.Ordered;
@Aspect("pertarget(execution(* *.getSpouse()))")
public class PerTargetAspect implements Ordered {
public int count;
private int order = Ordered.LOWEST_PRECEDENCE;
@Around("execution(int *.getAge())")
public int returnCountAsAge() {
return count++;
}
@Before("execution(void *.set*(int))")
public void countSetter() {
++count;
}
public int getOrder() {
return this.order;
}
public void setOrder(int order) {
this.order = order;
}
}
\ No newline at end of file
/*
* Copyright 2002-2005 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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 example.aspects;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
@Aspect("perthis(execution(* getAge()))")
public class PerThisAspect {
private int invocations = 0;
public int getInvocations() {
return this.invocations;
}
@Around("execution(* getAge())")
public int changeAge(ProceedingJoinPoint pjp) throws Throwable {
return invocations++;
}
}
/**
*
*/
package example.aspects;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class TwoAdviceAspect {
private int totalCalls;
@Around("execution(* getAge())")
public int returnCallCount(ProceedingJoinPoint pjp) throws Exception {
return totalCalls;
}
@Before("execution(* setAge(int)) && args(newAge)")
public void countSet(int newAge) throws Exception {
++totalCalls;
}
}
\ No newline at end of file
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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 example.scannable;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
/**
* @author Mark Fisher
*/
public class AutowiredQualifierFooService implements FooService {
@Autowired
@Qualifier("testing")
private FooDao fooDao;
private boolean initCalled = false;
@PostConstruct
private void init() {
if (this.initCalled) {
throw new IllegalStateException("Init already called");
}
this.initCalled = true;
}
public String foo(int id) {
return this.fooDao.findFoo(id);
}
public boolean isInitCalled() {
return this.initCalled;
}
}
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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 example.scannable;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author Mark Fisher
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface CustomComponent {
}
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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 example.scannable;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.stereotype.Component;
/**
* @author Juergen Hoeller
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface CustomStereotype {
String value() default "thoreau";
}
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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 example.scannable;
/**
* @author Juergen Hoeller
*/
@CustomStereotype
public class DefaultNamedComponent {
}
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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 example.scannable;
/**
* @author Mark Fisher
*/
public interface FooDao {
String findFoo(int id);
}
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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 example.scannable;
/**
* @author Mark Fisher
* @author Juergen Hoeller
*/
public interface FooService {
String foo(int id);
boolean isInitCalled();
}
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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 example.scannable;
import java.util.List;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.MessageSource;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.stereotype.Service;
/**
* @author Mark Fisher
* @author Juergen Hoeller
*/
@Service
public class FooServiceImpl implements FooService {
@Autowired private FooDao fooDao;
@Autowired public BeanFactory beanFactory;
@Autowired public List<ListableBeanFactory> listableBeanFactory;
@Autowired public ResourceLoader resourceLoader;
@Autowired public ResourcePatternResolver resourcePatternResolver;
@Autowired public ApplicationEventPublisher eventPublisher;
@Autowired public MessageSource messageSource;
@Autowired public ApplicationContext context;
@Autowired public ConfigurableApplicationContext[] configurableContext;
@Autowired public AbstractApplicationContext genericContext;
private boolean initCalled = false;
@PostConstruct
private void init() {
if (this.initCalled) {
throw new IllegalStateException("Init already called");
}
this.initCalled = true;
}
public String foo(int id) {
return this.fooDao.findFoo(id);
}
public boolean isInitCalled() {
return this.initCalled;
}
}
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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 example.scannable;
/**
* @author Mark Fisher
*/
@CustomComponent
public class MessageBean {
private String message;
public MessageBean() {
this.message = "DEFAULT MESSAGE";
}
public MessageBean(String message) {
this.message = message;
}
public String getMessage() {
return this.message;
}
}
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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 example.scannable;
import org.springframework.stereotype.Component;
/**
* @author Mark Fisher
*/
@Component("myNamedComponent")
public class NamedComponent {
}
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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 example.scannable;
import org.springframework.stereotype.Repository;
/**
* @author Juergen Hoeller
*/
@Repository("myNamedDao")
public class NamedStubDao {
public String find(int id) {
return "bar";
}
}
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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 example.scannable;
import org.springframework.context.annotation.Scope;
/**
* @author Mark Fisher
* @author Juergen Hoeller
*/
@Scope("myScope")
public class ScopedProxyTestBean implements FooService {
public String foo(int id) {
return "bar";
}
public boolean isInitCalled() {
return false;
}
}
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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 example.scannable;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/**
* @author Mark Fisher
*/
@Component
@Aspect
public class ServiceInvocationCounter {
private int useCount;
@Pointcut("execution(* example.scannable.FooService+.*(..))")
public void serviceExecution() {}
@Before("serviceExecution()")
public void countUse() {
this.useCount++;
}
public int getCount() {
return this.useCount;
}
}
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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 example.scannable;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;
/**
* @author Mark Fisher
*/
@Repository
@Qualifier("testing")
public class StubFooDao implements FooDao {
public String findFoo(int id) {
return "bar";
}
}
......@@ -16,8 +16,7 @@
package org.springframework.aop.framework;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import java.io.FileNotFoundException;
......
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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.springframework.mock.jndi;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.naming.NamingException;
import org.springframework.core.CollectionFactory;
import org.springframework.jndi.JndiTemplate;
/**
* Simple extension of the JndiTemplate class that always returns
* a given object. Very useful for testing. Effectively a mock object.
*
* @author Rod Johnson
* @author Juergen Hoeller
*/
public class ExpectedLookupTemplate extends JndiTemplate {
private final Map<String, Object> jndiObjects = new ConcurrentHashMap<String, Object>();
/**
* Construct a new JndiTemplate that will always return given objects
* for given names. To be populated through <code>addObject</code> calls.
* @see #addObject(String, Object)
*/
public ExpectedLookupTemplate() {
}
/**
* Construct a new JndiTemplate that will always return the
* given object, but honour only requests for the given name.
* @param name the name the client is expected to look up
* @param object the object that will be returned
*/
public ExpectedLookupTemplate(String name, Object object) {
addObject(name, object);
}
/**
* Add the given object to the list of JNDI objects that this
* template will expose.
* @param name the name the client is expected to look up
* @param object the object that will be returned
*/
public void addObject(String name, Object object) {
this.jndiObjects.put(name, object);
}
/**
* If the name is the expected name specified in the constructor,
* return the object provided in the constructor. If the name is
* unexpected, a respective NamingException gets thrown.
*/
public Object lookup(String name) throws NamingException {
Object object = this.jndiObjects.get(name);
if (object == null) {
throw new NamingException("Unexpected JNDI name '" + name + "': expecting " + this.jndiObjects.keySet());
}
return object;
}
}
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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.springframework.mock.jndi;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import javax.naming.Binding;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NameClassPair;
import javax.naming.NameNotFoundException;
import javax.naming.NameParser;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.OperationNotSupportedException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.StringUtils;
/**
* Simple implementation of a JNDI naming context.
* Only supports binding plain Objects to String names.
* Mainly for test environments, but also usable for standalone applications.
*
* <p>This class is not intended for direct usage by applications, although it
* can be used for example to override JndiTemplate's <code>createInitialContext</code>
* method in unit tests. Typically, SimpleNamingContextBuilder will be used to
* set up a JVM-level JNDI environment.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @see org.springframework.mock.jndi.SimpleNamingContextBuilder
* @see org.springframework.jndi.JndiTemplate#createInitialContext
*/
public class SimpleNamingContext implements Context {
private final Log logger = LogFactory.getLog(getClass());
private final String root;
private final Hashtable<String, Object> boundObjects;
private final Hashtable<String, Object> environment = new Hashtable<String, Object>();
/**
* Create a new naming context.
*/
public SimpleNamingContext() {
this("");
}
/**
* Create a new naming context with the given naming root.
*/
public SimpleNamingContext(String root) {
this.root = root;
this.boundObjects = new Hashtable<String, Object>();
}
/**
* Create a new naming context with the given naming root,
* the given name/object map, and the JNDI environment entries.
*/
public SimpleNamingContext(String root, Hashtable<String, Object> boundObjects, Hashtable<String, Object> env) {
this.root = root;
this.boundObjects = boundObjects;
if (env != null) {
this.environment.putAll(env);
}
}
// Actual implementations of Context methods follow
public NamingEnumeration<NameClassPair> list(String root) throws NamingException {
if (logger.isDebugEnabled()) {
logger.debug("Listing name/class pairs under [" + root + "]");
}
return new NameClassPairEnumeration(this, root);
}
public NamingEnumeration<Binding> listBindings(String root) throws NamingException {
if (logger.isDebugEnabled()) {
logger.debug("Listing bindings under [" + root + "]");
}
return new BindingEnumeration(this, root);
}
/**
* Look up the object with the given name.
* <p>Note: Not intended for direct use by applications.
* Will be used by any standard InitialContext JNDI lookups.
* @throws javax.naming.NameNotFoundException if the object could not be found
*/
public Object lookup(String lookupName) throws NameNotFoundException {
String name = this.root + lookupName;
if (logger.isDebugEnabled()) {
logger.debug("Static JNDI lookup: [" + name + "]");
}
if ("".equals(name)) {
return new SimpleNamingContext(this.root, this.boundObjects, this.environment);
}
Object found = this.boundObjects.get(name);
if (found == null) {
if (!name.endsWith("/")) {
name = name + "/";
}
for (String boundName : this.boundObjects.keySet()) {
if (boundName.startsWith(name)) {
return new SimpleNamingContext(name, this.boundObjects, this.environment);
}
}
throw new NameNotFoundException(
"Name [" + this.root + lookupName + "] not bound; " + this.boundObjects.size() + " bindings: [" +
StringUtils.collectionToDelimitedString(this.boundObjects.keySet(), ",") + "]");
}
return found;
}
public Object lookupLink(String name) throws NameNotFoundException {
return lookup(name);
}
/**
* Bind the given object to the given name.
* Note: Not intended for direct use by applications
* if setting up a JVM-level JNDI environment.
* Use SimpleNamingContextBuilder to set up JNDI bindings then.
* @see org.springframework.mock.jndi.SimpleNamingContextBuilder#bind
*/
public void bind(String name, Object obj) {
if (logger.isInfoEnabled()) {
logger.info("Static JNDI binding: [" + this.root + name + "] = [" + obj + "]");
}
this.boundObjects.put(this.root + name, obj);
}
public void unbind(String name) {
if (logger.isInfoEnabled()) {
logger.info("Static JNDI remove: [" + this.root + name + "]");
}
this.boundObjects.remove(this.root + name);
}
public void rebind(String name, Object obj) {
bind(name, obj);
}
public void rename(String oldName, String newName) throws NameNotFoundException {
Object obj = lookup(oldName);
unbind(oldName);
bind(newName, obj);
}
public Context createSubcontext(String name) {
String subcontextName = this.root + name;
if (!subcontextName.endsWith("/")) {
subcontextName += "/";
}
Context subcontext = new SimpleNamingContext(subcontextName, this.boundObjects, this.environment);
bind(name, subcontext);
return subcontext;
}
public void destroySubcontext(String name) {
unbind(name);
}
public String composeName(String name, String prefix) {
return prefix + name;
}
public Hashtable<String, Object> getEnvironment() {
return this.environment;
}
public Object addToEnvironment(String propName, Object propVal) {
return this.environment.put(propName, propVal);
}
public Object removeFromEnvironment(String propName) {
return this.environment.remove(propName);
}
public void close() {
}
// Unsupported methods follow: no support for javax.naming.Name
public NamingEnumeration<NameClassPair> list(Name name) throws NamingException {
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
}
public NamingEnumeration<Binding> listBindings(Name name) throws NamingException {
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
}
public Object lookup(Name name) throws NamingException {
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
}
public Object lookupLink(Name name) throws NamingException {
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
}
public void bind(Name name, Object obj) throws NamingException {
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
}
public void unbind(Name name) throws NamingException {
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
}
public void rebind(Name name, Object obj) throws NamingException {
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
}
public void rename(Name oldName, Name newName) throws NamingException {
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
}
public Context createSubcontext(Name name) throws NamingException {
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
}
public void destroySubcontext(Name name) throws NamingException {
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
}
public String getNameInNamespace() throws NamingException {
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
}
public NameParser getNameParser(Name name) throws NamingException {
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
}
public NameParser getNameParser(String name) throws NamingException {
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
}
public Name composeName(Name name, Name prefix) throws NamingException {
throw new OperationNotSupportedException("SimpleNamingContext does not support [javax.naming.Name]");
}
private static abstract class AbstractNamingEnumeration<T> implements NamingEnumeration<T> {
private Iterator<T> iterator;
private AbstractNamingEnumeration(SimpleNamingContext context, String proot) throws NamingException {
if (!"".equals(proot) && !proot.endsWith("/")) {
proot = proot + "/";
}
String root = context.root + proot;
Map<String, T> contents = new HashMap<String, T>();
for (String boundName : context.boundObjects.keySet()) {
if (boundName.startsWith(root)) {
int startIndex = root.length();
int endIndex = boundName.indexOf('/', startIndex);
String strippedName =
(endIndex != -1 ? boundName.substring(startIndex, endIndex) : boundName.substring(startIndex));
if (!contents.containsKey(strippedName)) {
try {
contents.put(strippedName, createObject(strippedName, context.lookup(proot + strippedName)));
}
catch (NameNotFoundException ex) {
// cannot happen
}
}
}
}
if (contents.size() == 0) {
throw new NamingException("Invalid root: [" + context.root + proot + "]");
}
this.iterator = contents.values().iterator();
}
protected abstract T createObject(String strippedName, Object obj);
public boolean hasMore() {
return this.iterator.hasNext();
}
public T next() {
return this.iterator.next();
}
public boolean hasMoreElements() {
return this.iterator.hasNext();
}
public T nextElement() {
return this.iterator.next();
}
public void close() {
}
}
private static class NameClassPairEnumeration extends AbstractNamingEnumeration<NameClassPair> {
private NameClassPairEnumeration(SimpleNamingContext context, String root) throws NamingException {
super(context, root);
}
protected NameClassPair createObject(String strippedName, Object obj) {
return new NameClassPair(strippedName, obj.getClass().getName());
}
}
private static class BindingEnumeration extends AbstractNamingEnumeration<Binding> {
private BindingEnumeration(SimpleNamingContext context, String root) throws NamingException {
super(context, root);
}
protected Binding createObject(String strippedName, Object obj) {
return new Binding(strippedName, obj);
}
}
}
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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.springframework.mock.jndi;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.spi.InitialContextFactory;
import javax.naming.spi.InitialContextFactoryBuilder;
import javax.naming.spi.NamingManager;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.ClassUtils;
/**
* Simple implementation of a JNDI naming context builder.
*
* <p>Mainly targeted at test environments, where each test case can
* configure JNDI appropriately, so that <code>new InitialContext()</code>
* will expose the required objects. Also usable for standalone applications,
* e.g. for binding a JDBC DataSource to a well-known JNDI location, to be
* able to use traditional J2EE data access code outside of a J2EE container.
*
* <p>There are various choices for DataSource implementations:
* <ul>
* <li>SingleConnectionDataSource (using the same Connection for all getConnection calls);
* <li>DriverManagerDataSource (creating a new Connection on each getConnection call);
* <li>Apache's Jakarta Commons DBCP offers BasicDataSource (a real pool).
* </ul>
*
* <p>Typical usage in bootstrap code:
*
* <pre class="code">
* SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
* DataSource ds = new DriverManagerDataSource(...);
* builder.bind("java:comp/env/jdbc/myds", ds);
* builder.activate();</pre>
*
* Note that it's impossible to activate multiple builders within the same JVM,
* due to JNDI restrictions. Thus to configure a fresh builder repeatedly, use
* the following code to get a reference to either an already activated builder
* or a newly activated one:
*
* <pre class="code">
* SimpleNamingContextBuilder builder = SimpleNamingContextBuilder.emptyActivatedContextBuilder();
* DataSource ds = new DriverManagerDataSource(...);
* builder.bind("java:comp/env/jdbc/myds", ds);</pre>
*
* Note that you <i>should not</i> call <code>activate()</code> on a builder from
* this factory method, as there will already be an activated one in any case.
*
* <p>An instance of this class is only necessary at setup time.
* An application does not need to keep a reference to it after activation.
*
* @author Juergen Hoeller
* @author Rod Johnson
* @see #emptyActivatedContextBuilder()
* @see #bind(String, Object)
* @see #activate()
* @see org.springframework.mock.jndi.SimpleNamingContext
* @see org.springframework.jdbc.datasource.SingleConnectionDataSource
* @see org.springframework.jdbc.datasource.DriverManagerDataSource
* @see org.apache.commons.dbcp.BasicDataSource
*/
public class SimpleNamingContextBuilder implements InitialContextFactoryBuilder {
/** An instance of this class bound to JNDI */
private static volatile SimpleNamingContextBuilder activated;
private static boolean initialized = false;
private static final Object initializationLock = new Object();
/**
* Checks if a SimpleNamingContextBuilder is active.
* @return the current SimpleNamingContextBuilder instance,
* or <code>null</code> if none
*/
public static SimpleNamingContextBuilder getCurrentContextBuilder() {
return activated;
}
/**
* If no SimpleNamingContextBuilder is already configuring JNDI,
* create and activate one. Otherwise take the existing activate
* SimpleNamingContextBuilder, clear it and return it.
* <p>This is mainly intended for test suites that want to
* reinitialize JNDI bindings from scratch repeatedly.
* @return an empty SimpleNamingContextBuilder that can be used
* to control JNDI bindings
*/
public static SimpleNamingContextBuilder emptyActivatedContextBuilder() throws NamingException {
if (activated != null) {
// Clear already activated context builder.
activated.clear();
}
else {
// Create and activate new context builder.
SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
// The activate() call will cause an assigment to the activated variable.
builder.activate();
}
return activated;
}
private final Log logger = LogFactory.getLog(getClass());
private final Hashtable boundObjects = new Hashtable();
/**
* Register the context builder by registering it with the JNDI NamingManager.
* Note that once this has been done, <code>new InitialContext()</code> will always
* return a context from this factory. Use the <code>emptyActivatedContextBuilder()</code>
* static method to get an empty context (for example, in test methods).
* @throws IllegalStateException if there's already a naming context builder
* registered with the JNDI NamingManager
*/
public void activate() throws IllegalStateException, NamingException {
logger.info("Activating simple JNDI environment");
synchronized (initializationLock) {
if (!initialized) {
if (NamingManager.hasInitialContextFactoryBuilder()) {
throw new IllegalStateException(
"Cannot activate SimpleNamingContextBuilder: there is already a JNDI provider registered. " +
"Note that JNDI is a JVM-wide service, shared at the JVM system class loader level, " +
"with no reset option. As a consequence, a JNDI provider must only be registered once per JVM.");
}
NamingManager.setInitialContextFactoryBuilder(this);
initialized = true;
}
}
activated = this;
}
/**
* Temporarily deactivate this context builder. It will remain registered with
* the JNDI NamingManager but will delegate to the standard JNDI InitialContextFactory
* (if configured) instead of exposing its own bound objects.
* <p>Call <code>activate()</code> again in order to expose this contexz builder's own
* bound objects again. Such activate/deactivate sequences can be applied any number
* of times (e.g. within a larger integration test suite running in the same VM).
* @see #activate()
*/
public void deactivate() {
logger.info("Deactivating simple JNDI environment");
activated = null;
}
/**
* Clear all bindings in this context builder, while keeping it active.
*/
public void clear() {
this.boundObjects.clear();
}
/**
* Bind the given object under the given name, for all naming contexts
* that this context builder will generate.
* @param name the JNDI name of the object (e.g. "java:comp/env/jdbc/myds")
* @param obj the object to bind (e.g. a DataSource implementation)
*/
public void bind(String name, Object obj) {
if (logger.isInfoEnabled()) {
logger.info("Static JNDI binding: [" + name + "] = [" + obj + "]");
}
this.boundObjects.put(name, obj);
}
/**
* Simple InitialContextFactoryBuilder implementation,
* creating a new SimpleNamingContext instance.
* @see SimpleNamingContext
*/
public InitialContextFactory createInitialContextFactory(Hashtable environment) {
if (activated == null && environment != null) {
Object icf = environment.get(Context.INITIAL_CONTEXT_FACTORY);
if (icf != null) {
Class icfClass = null;
if (icf instanceof Class) {
icfClass = (Class) icf;
}
else if (icf instanceof String) {
icfClass = ClassUtils.resolveClassName((String) icf, getClass().getClassLoader());
}
else {
throw new IllegalArgumentException("Invalid value type for environment key [" +
Context.INITIAL_CONTEXT_FACTORY + "]: " + icf.getClass().getName());
}
if (!InitialContextFactory.class.isAssignableFrom(icfClass)) {
throw new IllegalArgumentException(
"Specified class does not implement [" + InitialContextFactory.class.getName() + "]: " + icf);
}
try {
return (InitialContextFactory) icfClass.newInstance();
}
catch (Throwable ex) {
IllegalStateException ise =
new IllegalStateException("Cannot instantiate specified InitialContextFactory: " + icf);
ise.initCause(ex);
throw ise;
}
}
}
// Default case...
return new InitialContextFactory() {
public Context getInitialContext(Hashtable environment) {
return new SimpleNamingContext("", boundObjects, environment);
}
};
}
}
......@@ -20,12 +20,9 @@ import javax.transaction.RollbackException;
import javax.transaction.Status;
import javax.transaction.UserTransaction;
import com.ibm.wsspi.uow.UOWAction;
import com.ibm.wsspi.uow.UOWException;
import com.ibm.wsspi.uow.UOWManager;
import junit.framework.TestCase;
import org.easymock.MockControl;
import org.easymock.MockControl;
import org.springframework.dao.OptimisticLockingFailureException;
import org.springframework.mock.jndi.ExpectedLookupTemplate;
import org.springframework.transaction.IllegalTransactionStateException;
......@@ -37,6 +34,10 @@ import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import com.ibm.wsspi.uow.UOWAction;
import com.ibm.wsspi.uow.UOWException;
import com.ibm.wsspi.uow.UOWManager;
/**
* @author Juergen Hoeller
*/
......
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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.springframework.mock.web.portlet;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import javax.portlet.ActionRequest;
import javax.portlet.PortalContext;
import javax.portlet.PortletContext;
import javax.portlet.PortletMode;
/**
* Mock implementation of the {@link javax.portlet.ActionRequest} interface.
*
* @author John A. Lewis
* @author Juergen Hoeller
* @since 2.0
*/
public class MockActionRequest extends MockPortletRequest implements ActionRequest {
private String characterEncoding;
private byte[] content;
private String contentType;
/**
* Create a new MockActionRequest with a default {@link MockPortalContext}
* and a default {@link MockPortletContext}.
* @see MockPortalContext
* @see MockPortletContext
*/
public MockActionRequest() {
super();
}
/**
* Create a new MockActionRequest with a default {@link MockPortalContext}
* and a default {@link MockPortletContext}.
* @param portletMode the mode that the portlet runs in
*/
public MockActionRequest(PortletMode portletMode) {
super();
setPortletMode(portletMode);
}
/**
* Create a new MockActionRequest with a default {@link MockPortalContext}.
* @param portletContext the PortletContext that the request runs in
*/
public MockActionRequest(PortletContext portletContext) {
super(portletContext);
}
/**
* Create a new MockActionRequest.
* @param portalContext the PortalContext that the request runs in
* @param portletContext the PortletContext that the request runs in
*/
public MockActionRequest(PortalContext portalContext, PortletContext portletContext) {
super(portalContext, portletContext);
}
public void setContent(byte[] content) {
this.content = content;
}
public InputStream getPortletInputStream() throws IOException {
if (this.content != null) {
return new ByteArrayInputStream(this.content);
}
else {
return null;
}
}
public void setCharacterEncoding(String characterEncoding) {
this.characterEncoding = characterEncoding;
}
public BufferedReader getReader() throws UnsupportedEncodingException {
if (this.content != null) {
InputStream sourceStream = new ByteArrayInputStream(this.content);
Reader sourceReader = (this.characterEncoding != null) ?
new InputStreamReader(sourceStream, this.characterEncoding) : new InputStreamReader(sourceStream);
return new BufferedReader(sourceReader);
}
else {
return null;
}
}
public String getCharacterEncoding() {
return characterEncoding;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
public String getContentType() {
return contentType;
}
public int getContentLength() {
return (this.content != null ? content.length : -1);
}
}
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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.springframework.mock.web.portlet;
import java.io.IOException;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.portlet.ActionResponse;
import javax.portlet.PortalContext;
import javax.portlet.PortletMode;
import javax.portlet.PortletModeException;
import javax.portlet.WindowState;
import javax.portlet.WindowStateException;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
/**
* Mock implementation of the {@link javax.portlet.ActionResponse} interface.
*
* @author John A. Lewis
* @author Juergen Hoeller
* @since 2.0
*/
public class MockActionResponse extends MockPortletResponse implements ActionResponse {
private WindowState windowState;
private PortletMode portletMode;
private String redirectedUrl;
private final Map<String, String[]> renderParameters = new LinkedHashMap<String, String[]>();
/**
* Create a new MockActionResponse with a default {@link MockPortalContext}.
* @see MockPortalContext
*/
public MockActionResponse() {
super();
}
/**
* Create a new MockActionResponse.
* @param portalContext the PortalContext defining the supported
* PortletModes and WindowStates
*/
public MockActionResponse(PortalContext portalContext) {
super(portalContext);
}
public void setWindowState(WindowState windowState) throws WindowStateException {
if (this.redirectedUrl != null) {
throw new IllegalStateException("Cannot set WindowState after sendRedirect has been called");
}
if (!CollectionUtils.contains(getPortalContext().getSupportedWindowStates(), windowState)) {
throw new WindowStateException("WindowState not supported", windowState);
}
this.windowState = windowState;
}
public WindowState getWindowState() {
return windowState;
}
public void setPortletMode(PortletMode portletMode) throws PortletModeException {
if (this.redirectedUrl != null) {
throw new IllegalStateException("Cannot set PortletMode after sendRedirect has been called");
}
if (!CollectionUtils.contains(getPortalContext().getSupportedPortletModes(), portletMode)) {
throw new PortletModeException("PortletMode not supported", portletMode);
}
this.portletMode = portletMode;
}
public PortletMode getPortletMode() {
return portletMode;
}
public void sendRedirect(String url) throws IOException {
if (this.windowState != null || this.portletMode != null || !this.renderParameters.isEmpty()) {
throw new IllegalStateException(
"Cannot call sendRedirect after windowState, portletMode, or renderParameters have been set");
}
Assert.notNull(url, "Redirect URL must not be null");
this.redirectedUrl = url;
}
public String getRedirectedUrl() {
return redirectedUrl;
}
public void setRenderParameters(Map parameters) {
if (this.redirectedUrl != null) {
throw new IllegalStateException("Cannot set render parameters after sendRedirect has been called");
}
Assert.notNull(parameters, "Parameters Map must not be null");
this.renderParameters.clear();
for (Iterator it = parameters.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
Assert.isTrue(entry.getKey() instanceof String, "Key must be of type String");
Assert.isTrue(entry.getValue() instanceof String[], "Value must be of type String[]");
this.renderParameters.put((String) entry.getKey(), (String[]) entry.getValue());
}
}
public void setRenderParameter(String key, String value) {
if (this.redirectedUrl != null) {
throw new IllegalStateException("Cannot set render parameters after sendRedirect has been called");
}
Assert.notNull(key, "Parameter key must not be null");
Assert.notNull(value, "Parameter value must not be null");
this.renderParameters.put(key, new String[] {value});
}
public String getRenderParameter(String key) {
Assert.notNull(key, "Parameter key must not be null");
String[] arr = this.renderParameters.get(key);
return (arr != null && arr.length > 0 ? arr[0] : null);
}
public void setRenderParameter(String key, String[] values) {
if (this.redirectedUrl != null) {
throw new IllegalStateException("Cannot set render parameters after sendRedirect has been called");
}
Assert.notNull(key, "Parameter key must not be null");
Assert.notNull(values, "Parameter values must not be null");
this.renderParameters.put(key, values);
}
public String[] getRenderParameterValues(String key) {
Assert.notNull(key, "Parameter key must not be null");
return this.renderParameters.get(key);
}
public Iterator getRenderParameterNames() {
return this.renderParameters.keySet().iterator();
}
public Map getRenderParameterMap() {
return Collections.unmodifiableMap(this.renderParameters);
}
}
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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.springframework.mock.web.portlet;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.portlet.multipart.MultipartActionRequest;
/**
* Mock implementation of the
* {@link org.springframework.web.portlet.multipart.MultipartActionRequest} interface.
*
* <p>Useful for testing application controllers that access multipart uploads.
* The {@link org.springframework.mock.web.MockMultipartFile} can be used to
* populate these mock requests with files.
*
* @author Juergen Hoeller
* @since 2.0
* @see org.springframework.mock.web.MockMultipartFile
*/
public class MockMultipartActionRequest extends MockActionRequest implements MultipartActionRequest {
private final Map<String, MultipartFile> multipartFiles = new LinkedHashMap<String, MultipartFile>();
/**
* Add a file to this request. The parameter name from the multipart
* form is taken from the {@link org.springframework.web.multipart.MultipartFile#getName()}.
* @param file multipart file to be added
*/
public void addFile(MultipartFile file) {
Assert.notNull(file, "MultipartFile must not be null");
this.multipartFiles.put(file.getName(), file);
}
public Iterator<String> getFileNames() {
return getFileMap().keySet().iterator();
}
public MultipartFile getFile(String name) {
return this.multipartFiles.get(name);
}
public Map<String, MultipartFile> getFileMap() {
return Collections.unmodifiableMap(this.multipartFiles);
}
}
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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.springframework.mock.web.portlet;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.portlet.PortalContext;
import javax.portlet.PortletMode;
import javax.portlet.WindowState;
/**
* Mock implementation of the {@link javax.portlet.PortalContext} interface.
*
* @author John A. Lewis
* @author Juergen Hoeller
* @since 2.0
*/
public class MockPortalContext implements PortalContext {
private final Map<String, String> properties = new HashMap<String, String>();
private final List<PortletMode> portletModes;
private final List<WindowState> windowStates;
/**
* Create a new MockPortalContext
* with default PortletModes (VIEW, EDIT, HELP)
* and default WindowStates (NORMAL, MAXIMIZED, MINIMIZED).
* @see javax.portlet.PortletMode
* @see javax.portlet.WindowState
*/
public MockPortalContext() {
this.portletModes = new ArrayList<PortletMode>(3);
this.portletModes.add(PortletMode.VIEW);
this.portletModes.add(PortletMode.EDIT);
this.portletModes.add(PortletMode.HELP);
this.windowStates = new ArrayList<WindowState>(3);
this.windowStates.add(WindowState.NORMAL);
this.windowStates.add(WindowState.MAXIMIZED);
this.windowStates.add(WindowState.MINIMIZED);
}
/**
* Create a new MockPortalContext with the given PortletModes and WindowStates.
* @param supportedPortletModes the List of supported PortletMode instances
* @param supportedWindowStates the List of supported WindowState instances
* @see javax.portlet.PortletMode
* @see javax.portlet.WindowState
*/
public MockPortalContext(List<PortletMode> supportedPortletModes, List<WindowState> supportedWindowStates) {
this.portletModes = new ArrayList<PortletMode>(supportedPortletModes);
this.windowStates = new ArrayList<WindowState>(supportedWindowStates);
}
public String getPortalInfo() {
return "MockPortal/1.0";
}
public void setProperty(String name, String value) {
this.properties.put(name, value);
}
public String getProperty(String name) {
return this.properties.get(name);
}
public Enumeration<String> getPropertyNames() {
return Collections.enumeration(this.properties.keySet());
}
public Enumeration<PortletMode> getSupportedPortletModes() {
return Collections.enumeration(this.portletModes);
}
public Enumeration<WindowState> getSupportedWindowStates() {
return Collections.enumeration(this.windowStates);
}
}
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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.springframework.mock.web.portlet;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.LinkedHashMap;
import java.util.Collections;
import javax.portlet.PortletConfig;
import javax.portlet.PortletContext;
import org.springframework.util.Assert;
/**
* Mock implementation of the {@link javax.portlet.PortletConfig} interface.
*
* @author John A. Lewis
* @author Juergen Hoeller
* @since 2.0
*/
public class MockPortletConfig implements PortletConfig {
private final PortletContext portletContext;
private final String portletName;
private final Map<Locale, ResourceBundle> resourceBundles = new HashMap<Locale, ResourceBundle>();
private final Map<String, String> initParameters = new LinkedHashMap<String, String>();
/**
* Create a new MockPortletConfig with a default {@link MockPortletContext}.
*/
public MockPortletConfig() {
this(null, "");
}
/**
* Create a new MockPortletConfig with a default {@link MockPortletContext}.
* @param portletName the name of the portlet
*/
public MockPortletConfig(String portletName) {
this(null, portletName);
}
/**
* Create a new MockPortletConfig.
* @param portletContext the PortletContext that the portlet runs in
*/
public MockPortletConfig(PortletContext portletContext) {
this(portletContext, "");
}
/**
* Create a new MockPortletConfig.
* @param portletContext the PortletContext that the portlet runs in
* @param portletName the name of the portlet
*/
public MockPortletConfig(PortletContext portletContext, String portletName) {
this.portletContext = (portletContext != null ? portletContext : new MockPortletContext());
this.portletName = portletName;
}
public String getPortletName() {
return this.portletName;
}
public PortletContext getPortletContext() {
return this.portletContext;
}
public void setResourceBundle(Locale locale, ResourceBundle resourceBundle) {
Assert.notNull(locale, "Locale must not be null");
this.resourceBundles.put(locale, resourceBundle);
}
public ResourceBundle getResourceBundle(Locale locale) {
Assert.notNull(locale, "Locale must not be null");
return this.resourceBundles.get(locale);
}
public void addInitParameter(String name, String value) {
Assert.notNull(name, "Parameter name must not be null");
this.initParameters.put(name, value);
}
public String getInitParameter(String name) {
Assert.notNull(name, "Parameter name must not be null");
return this.initParameters.get(name);
}
public Enumeration<String> getInitParameterNames() {
return Collections.enumeration(this.initParameters.keySet());
}
}
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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.springframework.mock.web.portlet;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import javax.portlet.PortletContext;
import javax.portlet.PortletRequestDispatcher;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.Assert;
import org.springframework.web.util.WebUtils;
/**
* Mock implementation of the {@link javax.portlet.PortletContext} interface.
*
* @author John A. Lewis
* @author Juergen Hoeller
* @since 2.0
*/
public class MockPortletContext implements PortletContext {
private static final String TEMP_DIR_SYSTEM_PROPERTY = "java.io.tmpdir";
private final Log logger = LogFactory.getLog(getClass());
private final String resourceBasePath;
private final ResourceLoader resourceLoader;
private final Map<String, Object> attributes = new LinkedHashMap<String, Object>();
private final Map<String, String> initParameters = new LinkedHashMap<String, String>();
private String portletContextName = "MockPortletContext";
/**
* Create a new MockPortletContext with no base path and a
* DefaultResourceLoader (i.e. the classpath root as WAR root).
* @see org.springframework.core.io.DefaultResourceLoader
*/
public MockPortletContext() {
this("", null);
}
/**
* Create a new MockPortletContext using a DefaultResourceLoader.
* @param resourceBasePath the WAR root directory (should not end with a slash)
* @see org.springframework.core.io.DefaultResourceLoader
*/
public MockPortletContext(String resourceBasePath) {
this(resourceBasePath, null);
}
/**
* Create a new MockPortletContext, using the specified ResourceLoader
* and no base path.
* @param resourceLoader the ResourceLoader to use (or null for the default)
*/
public MockPortletContext(ResourceLoader resourceLoader) {
this("", resourceLoader);
}
/**
* Create a new MockPortletContext.
* @param resourceBasePath the WAR root directory (should not end with a slash)
* @param resourceLoader the ResourceLoader to use (or null for the default)
*/
public MockPortletContext(String resourceBasePath, ResourceLoader resourceLoader) {
this.resourceBasePath = (resourceBasePath != null ? resourceBasePath : "");
this.resourceLoader = (resourceLoader != null ? resourceLoader : new DefaultResourceLoader());
// Use JVM temp dir as PortletContext temp dir.
String tempDir = System.getProperty(TEMP_DIR_SYSTEM_PROPERTY);
if (tempDir != null) {
this.attributes.put(WebUtils.TEMP_DIR_CONTEXT_ATTRIBUTE, new File(tempDir));
}
}
/**
* Build a full resource location for the given path,
* prepending the resource base path of this MockPortletContext.
* @param path the path as specified
* @return the full resource path
*/
protected String getResourceLocation(String path) {
if (!path.startsWith("/")) {
path = "/" + path;
}
return this.resourceBasePath + path;
}
public String getServerInfo() {
return "MockPortal/1.0";
}
public PortletRequestDispatcher getRequestDispatcher(String path) {
if (!path.startsWith("/")) {
throw new IllegalArgumentException(
"PortletRequestDispatcher path at PortletContext level must start with '/'");
}
return new MockPortletRequestDispatcher(path);
}
public PortletRequestDispatcher getNamedDispatcher(String path) {
return null;
}
public InputStream getResourceAsStream(String path) {
Resource resource = this.resourceLoader.getResource(getResourceLocation(path));
try {
return resource.getInputStream();
}
catch (IOException ex) {
logger.info("Couldn't open InputStream for " + resource, ex);
return null;
}
}
public int getMajorVersion() {
return 1;
}
public int getMinorVersion() {
return 0;
}
public String getMimeType(String filePath) {
return null;
}
public String getRealPath(String path) {
Resource resource = this.resourceLoader.getResource(getResourceLocation(path));
try {
return resource.getFile().getAbsolutePath();
}
catch (IOException ex) {
logger.info("Couldn't determine real path of resource " + resource, ex);
return null;
}
}
public Set<String> getResourcePaths(String path) {
Resource resource = this.resourceLoader.getResource(getResourceLocation(path));
try {
File file = resource.getFile();
String[] fileList = file.list();
String prefix = (path.endsWith("/") ? path : path + "/");
Set<String> resourcePaths = new HashSet<String>(fileList.length);
for (String fileEntry : fileList) {
resourcePaths.add(prefix + fileEntry);
}
return resourcePaths;
}
catch (IOException ex) {
logger.info("Couldn't get resource paths for " + resource, ex);
return null;
}
}
public URL getResource(String path) throws MalformedURLException {
Resource resource = this.resourceLoader.getResource(getResourceLocation(path));
try {
return resource.getURL();
}
catch (IOException ex) {
logger.info("Couldn't get URL for " + resource, ex);
return null;
}
}
public Object getAttribute(String name) {
return this.attributes.get(name);
}
public Enumeration<String> getAttributeNames() {
return Collections.enumeration(this.attributes.keySet());
}
public void setAttribute(String name, Object value) {
if (value != null) {
this.attributes.put(name, value);
}
else {
this.attributes.remove(name);
}
}
public void removeAttribute(String name) {
this.attributes.remove(name);
}
public void addInitParameter(String name, String value) {
Assert.notNull(name, "Parameter name must not be null");
this.initParameters.put(name, value);
}
public String getInitParameter(String name) {
Assert.notNull(name, "Parameter name must not be null");
return this.initParameters.get(name);
}
public Enumeration<String> getInitParameterNames() {
return Collections.enumeration(this.initParameters.keySet());
}
public void log(String message) {
logger.info(message);
}
public void log(String message, Throwable t) {
logger.info(message, t);
}
public void setPortletContextName(String portletContextName) {
this.portletContextName = portletContextName;
}
public String getPortletContextName() {
return portletContextName;
}
}
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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.springframework.mock.web.portlet;
import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import javax.portlet.PortletPreferences;
import javax.portlet.PreferencesValidator;
import javax.portlet.ReadOnlyException;
import javax.portlet.ValidatorException;
import org.springframework.util.Assert;
/**
* Mock implementation of the {@link javax.portlet.PortletPreferences} interface.
*
* @author John A. Lewis
* @author Juergen Hoeller
* @since 2.0
*/
public class MockPortletPreferences implements PortletPreferences {
private PreferencesValidator preferencesValidator;
private final Map<String, String[]> preferences = new LinkedHashMap<String, String[]>();
private final Set<String> readOnly = new HashSet<String>();
public void setReadOnly(String key, boolean readOnly) {
Assert.notNull(key, "Key must not be null");
if (readOnly) {
this.readOnly.add(key);
}
else {
this.readOnly.remove(key);
}
}
public boolean isReadOnly(String key) {
Assert.notNull(key, "Key must not be null");
return this.readOnly.contains(key);
}
public String getValue(String key, String def) {
Assert.notNull(key, "Key must not be null");
String[] values = this.preferences.get(key);
return (values != null && values.length > 0 ? values[0] : def);
}
public String[] getValues(String key, String[] def) {
Assert.notNull(key, "Key must not be null");
String[] values = this.preferences.get(key);
return (values != null && values.length > 0 ? values : def);
}
public void setValue(String key, String value) throws ReadOnlyException {
setValues(key, new String[] {value});
}
public void setValues(String key, String[] values) throws ReadOnlyException {
Assert.notNull(key, "Key must not be null");
if (isReadOnly(key)) {
throw new ReadOnlyException("Preference '" + key + "' is read-only");
}
this.preferences.put(key, values);
}
public Enumeration<String> getNames() {
return Collections.enumeration(this.preferences.keySet());
}
public Map<String, String[]> getMap() {
return Collections.unmodifiableMap(this.preferences);
}
public void reset(String key) throws ReadOnlyException {
Assert.notNull(key, "Key must not be null");
if (isReadOnly(key)) {
throw new ReadOnlyException("Preference '" + key + "' is read-only");
}
this.preferences.remove(key);
}
public void setPreferencesValidator(PreferencesValidator preferencesValidator) {
this.preferencesValidator = preferencesValidator;
}
public void store() throws IOException, ValidatorException {
if (this.preferencesValidator != null) {
this.preferencesValidator.validate(this);
}
}
}
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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.springframework.mock.web.portlet;
import java.security.Principal;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import javax.portlet.PortalContext;
import javax.portlet.PortletContext;
import javax.portlet.PortletMode;
import javax.portlet.PortletPreferences;
import javax.portlet.PortletRequest;
import javax.portlet.PortletSession;
import javax.portlet.WindowState;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
/**
* Mock implementation of the {@link javax.portlet.PortletRequest} interface.
*
* @author John A. Lewis
* @author Juergen Hoeller
* @since 2.0
*/
public class MockPortletRequest implements PortletRequest {
private boolean active = true;
private final PortalContext portalContext;
private final PortletContext portletContext;
private PortletSession session;
private WindowState windowState = WindowState.NORMAL;
private PortletMode portletMode = PortletMode.VIEW;
private PortletPreferences portletPreferences = new MockPortletPreferences();
private final Map<String, List<String>> properties = new LinkedHashMap<String, List<String>>();
private final Map<String, Object> attributes = new LinkedHashMap<String, Object>();
private final Map<String, String[]> parameters = new LinkedHashMap<String, String[]>();
private String authType = null;
private String contextPath = "";
private String remoteUser = null;
private Principal userPrincipal = null;
private final Set<String> userRoles = new HashSet<String>();
private boolean secure = false;
private boolean requestedSessionIdValid = true;
private final List<String> responseContentTypes = new LinkedList<String>();
private final List<Locale> locales = new LinkedList<Locale>();
private String scheme = "http";
private String serverName = "localhost";
private int serverPort = 80;
/**
* Create a new MockPortletRequest with a default {@link MockPortalContext}
* and a default {@link MockPortletContext}.
* @see MockPortalContext
* @see MockPortletContext
*/
public MockPortletRequest() {
this(null, null);
}
/**
* Create a new MockPortletRequest with a default {@link MockPortalContext}.
* @param portletContext the PortletContext that the request runs in
* @see MockPortalContext
*/
public MockPortletRequest(PortletContext portletContext) {
this(null, portletContext);
}
/**
* Create a new MockPortletRequest.
* @param portalContext the PortalContext that the request runs in
* @param portletContext the PortletContext that the request runs in
*/
public MockPortletRequest(PortalContext portalContext, PortletContext portletContext) {
this.portalContext = (portalContext != null ? portalContext : new MockPortalContext());
this.portletContext = (portletContext != null ? portletContext : new MockPortletContext());
this.responseContentTypes.add("text/html");
this.locales.add(Locale.ENGLISH);
}
//---------------------------------------------------------------------
// Lifecycle methods
//---------------------------------------------------------------------
/**
* Return whether this request is still active (that is, not completed yet).
*/
public boolean isActive() {
return this.active;
}
/**
* Mark this request as completed.
*/
public void close() {
this.active = false;
}
/**
* Check whether this request is still active (that is, not completed yet),
* throwing an IllegalStateException if not active anymore.
*/
protected void checkActive() throws IllegalStateException {
if (!this.active) {
throw new IllegalStateException("Request is not active anymore");
}
}
//---------------------------------------------------------------------
// PortletRequest methods
//---------------------------------------------------------------------
public boolean isWindowStateAllowed(WindowState windowState) {
return CollectionUtils.contains(this.portalContext.getSupportedWindowStates(), windowState);
}
public boolean isPortletModeAllowed(PortletMode portletMode) {
return CollectionUtils.contains(this.portalContext.getSupportedPortletModes(), portletMode);
}
public void setPortletMode(PortletMode portletMode) {
Assert.notNull(portletMode, "PortletMode must not be null");
this.portletMode = portletMode;
}
public PortletMode getPortletMode() {
return this.portletMode;
}
public void setWindowState(WindowState windowState) {
Assert.notNull(windowState, "WindowState must not be null");
this.windowState = windowState;
}
public WindowState getWindowState() {
return this.windowState;
}
public void setPreferences(PortletPreferences preferences) {
Assert.notNull(preferences, "PortletPreferences must not be null");
this.portletPreferences = preferences;
}
public PortletPreferences getPreferences() {
return this.portletPreferences;
}
public void setSession(PortletSession session) {
this.session = session;
if (session instanceof MockPortletSession) {
MockPortletSession mockSession = ((MockPortletSession) session);
mockSession.access();
}
}
public PortletSession getPortletSession() {
return getPortletSession(true);
}
public PortletSession getPortletSession(boolean create) {
checkActive();
// Reset session if invalidated.
if (this.session instanceof MockPortletSession && ((MockPortletSession) this.session).isInvalid()) {
this.session = null;
}
// Create new session if necessary.
if (this.session == null && create) {
this.session = new MockPortletSession(this.portletContext);
}
return this.session;
}
/**
* Set a single value for the specified property.
* <p>If there are already one or more values registered for the given
* property key, they will be replaced.
*/
public void setProperty(String key, String value) {
Assert.notNull(key, "Property key must not be null");
List<String> list = new LinkedList<String>();
list.add(value);
this.properties.put(key, list);
}
/**
* Add a single value for the specified property.
* <p>If there are already one or more values registered for the given
* property key, the given value will be added to the end of the list.
*/
public void addProperty(String key, String value) {
Assert.notNull(key, "Property key must not be null");
List<String> oldList = this.properties.get(key);
if (oldList != null) {
oldList.add(value);
}
else {
List<String> list = new LinkedList<String>();
list.add(value);
this.properties.put(key, list);
}
}
public String getProperty(String key) {
Assert.notNull(key, "Property key must not be null");
List list = this.properties.get(key);
return (list != null && list.size() > 0 ? (String) list.get(0) : null);
}
public Enumeration<String> getProperties(String key) {
Assert.notNull(key, "property key must not be null");
return Collections.enumeration(this.properties.get(key));
}
public Enumeration<String> getPropertyNames() {
return Collections.enumeration(this.properties.keySet());
}
public PortalContext getPortalContext() {
return this.portalContext;
}
public void setAuthType(String authType) {
this.authType = authType;
}
public String getAuthType() {
return this.authType;
}
public void setContextPath(String contextPath) {
this.contextPath = contextPath;
}
public String getContextPath() {
return this.contextPath;
}
public void setRemoteUser(String remoteUser) {
this.remoteUser = remoteUser;
}
public String getRemoteUser() {
return this.remoteUser;
}
public void setUserPrincipal(Principal userPrincipal) {
this.userPrincipal = userPrincipal;
}
public Principal getUserPrincipal() {
return this.userPrincipal;
}
public void addUserRole(String role) {
this.userRoles.add(role);
}
public boolean isUserInRole(String role) {
return this.userRoles.contains(role);
}
public Object getAttribute(String name) {
checkActive();
return this.attributes.get(name);
}
public Enumeration<String> getAttributeNames() {
checkActive();
return Collections.enumeration(this.attributes.keySet());
}
public void setParameters(Map<String, String[]> parameters) {
Assert.notNull(parameters, "Parameters Map must not be null");
this.parameters.clear();
this.parameters.putAll(parameters);
}
public void setParameter(String key, String value) {
Assert.notNull(key, "Parameter key must be null");
Assert.notNull(value, "Parameter value must not be null");
this.parameters.put(key, new String[] {value});
}
public void setParameter(String key, String[] values) {
Assert.notNull(key, "Parameter key must be null");
Assert.notNull(values, "Parameter values must not be null");
this.parameters.put(key, values);
}
public void addParameter(String name, String value) {
addParameter(name, new String[] {value});
}
public void addParameter(String name, String[] values) {
String[] oldArr = this.parameters.get(name);
if (oldArr != null) {
String[] newArr = new String[oldArr.length + values.length];
System.arraycopy(oldArr, 0, newArr, 0, oldArr.length);
System.arraycopy(values, 0, newArr, oldArr.length, values.length);
this.parameters.put(name, newArr);
}
else {
this.parameters.put(name, values);
}
}
public String getParameter(String name) {
String[] arr = this.parameters.get(name);
return (arr != null && arr.length > 0 ? arr[0] : null);
}
public Enumeration<String> getParameterNames() {
return Collections.enumeration(this.parameters.keySet());
}
public String[] getParameterValues(String name) {
return this.parameters.get(name);
}
public Map getParameterMap() {
return Collections.unmodifiableMap(this.parameters);
}
public void setSecure(boolean secure) {
this.secure = secure;
}
public boolean isSecure() {
return this.secure;
}
public void setAttribute(String name, Object value) {
checkActive();
if (value != null) {
this.attributes.put(name, value);
}
else {
this.attributes.remove(name);
}
}
public void removeAttribute(String name) {
checkActive();
this.attributes.remove(name);
}
public String getRequestedSessionId() {
PortletSession session = this.getPortletSession();
return (session != null ? session.getId() : null);
}
public void setRequestedSessionIdValid(boolean requestedSessionIdValid) {
this.requestedSessionIdValid = requestedSessionIdValid;
}
public boolean isRequestedSessionIdValid() {
return this.requestedSessionIdValid;
}
public void addResponseContentType(String responseContentType) {
this.responseContentTypes.add(responseContentType);
}
public void addPreferredResponseContentType(String responseContentType) {
this.responseContentTypes.add(0, responseContentType);
}
public String getResponseContentType() {
return this.responseContentTypes.get(0);
}
public Enumeration<String> getResponseContentTypes() {
return Collections.enumeration(this.responseContentTypes);
}
public void addLocale(Locale locale) {
this.locales.add(locale);
}
public void addPreferredLocale(Locale locale) {
this.locales.add(0, locale);
}
public Locale getLocale() {
return this.locales.get(0);
}
public Enumeration<Locale> getLocales() {
return Collections.enumeration(this.locales);
}
public void setScheme(String scheme) {
this.scheme = scheme;
}
public String getScheme() {
return this.scheme;
}
public void setServerName(String serverName) {
this.serverName = serverName;
}
public String getServerName() {
return this.serverName;
}
public void setServerPort(int serverPort) {
this.serverPort = serverPort;
}
public int getServerPort() {
return this.serverPort;
}
}
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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.springframework.mock.web.portlet;
import java.io.IOException;
import javax.portlet.PortletException;
import javax.portlet.PortletRequestDispatcher;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
/**
* Mock implementation of the {@link javax.portlet.PortletRequestDispatcher} interface.
*
* @author John A. Lewis
* @author Juergen Hoeller
* @since 2.0
*/
public class MockPortletRequestDispatcher implements PortletRequestDispatcher {
private final Log logger = LogFactory.getLog(getClass());
private final String url;
/**
* Create a new MockPortletRequestDispatcher for the given URL.
* @param url the URL to dispatch to.
*/
public MockPortletRequestDispatcher(String url) {
Assert.notNull(url, "URL must not be null");
this.url = url;
}
public void include(RenderRequest request, RenderResponse response) throws PortletException, IOException {
Assert.notNull(request, "Request must not be null");
Assert.notNull(response, "Response must not be null");
if (!(response instanceof MockRenderResponse)) {
throw new IllegalArgumentException("MockPortletRequestDispatcher requires MockRenderResponse");
}
((MockRenderResponse) response).setIncludedUrl(this.url);
if (logger.isDebugEnabled()) {
logger.debug("MockPortletRequestDispatcher: including URL [" + this.url + "]");
}
}
}
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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.springframework.mock.web.portlet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import javax.portlet.PortalContext;
import javax.portlet.PortletResponse;
import org.springframework.util.Assert;
/**
* Mock implementation of the {@link javax.portlet.PortletResponse} interface.
*
* @author John A. Lewis
* @author Juergen Hoeller
* @since 2.0
*/
public class MockPortletResponse implements PortletResponse {
private final PortalContext portalContext;
private final Map<String, String[]> properties = new LinkedHashMap<String, String[]>();
/**
* Create a new MockPortletResponse with a default {@link MockPortalContext}.
* @see MockPortalContext
*/
public MockPortletResponse() {
this(null);
}
/**
* Create a new MockPortletResponse.
* @param portalContext the PortalContext defining the supported
* PortletModes and WindowStates
*/
public MockPortletResponse(PortalContext portalContext) {
this.portalContext = (portalContext != null ? portalContext : new MockPortalContext());
}
/**
* Return the PortalContext that this MockPortletResponse runs in,
* defining the supported PortletModes and WindowStates.
*/
public PortalContext getPortalContext() {
return this.portalContext;
}
//---------------------------------------------------------------------
// PortletResponse methods
//---------------------------------------------------------------------
public void addProperty(String key, String value) {
Assert.notNull(key, "Property key must not be null");
String[] oldArr = this.properties.get(key);
if (oldArr != null) {
String[] newArr = new String[oldArr.length + 1];
System.arraycopy(oldArr, 0, newArr, 0, oldArr.length);
newArr[oldArr.length] = value;
this.properties.put(key, newArr);
}
else {
this.properties.put(key, new String[] {value});
}
}
public void setProperty(String key, String value) {
Assert.notNull(key, "Property key must not be null");
this.properties.put(key, new String[] {value});
}
public Set getPropertyNames() {
return this.properties.keySet();
}
public String getProperty(String key) {
Assert.notNull(key, "Property key must not be null");
String[] arr = this.properties.get(key);
return (arr != null && arr.length > 0 ? arr[0] : null);
}
public String[] getProperties(String key) {
Assert.notNull(key, "Property key must not be null");
return this.properties.get(key);
}
public String encodeURL(String path) {
return path;
}
}
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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.springframework.mock.web.portlet;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.portlet.PortletContext;
import javax.portlet.PortletSession;
/**
* Mock implementation of the {@link javax.portlet.PortletSession} interface.
*
* @author John A. Lewis
* @author Juergen Hoeller
* @since 2.0
*/
public class MockPortletSession implements PortletSession {
private static int nextId = 1;
private final String id = Integer.toString(nextId++);
private final long creationTime = System.currentTimeMillis();
private int maxInactiveInterval;
private long lastAccessedTime = System.currentTimeMillis();
private final PortletContext portletContext;
private final Map<String, Object> portletAttributes = new HashMap<String, Object>();
private final Map<String, Object> applicationAttributes = new HashMap<String, Object>();
private boolean invalid = false;
private boolean isNew = true;
/**
* Create a new MockPortletSession with a default {@link MockPortletContext}.
* @see MockPortletContext
*/
public MockPortletSession() {
this(null);
}
/**
* Create a new MockPortletSession.
* @param portletContext the PortletContext that the session runs in
*/
public MockPortletSession(PortletContext portletContext) {
this.portletContext = (portletContext != null ? portletContext : new MockPortletContext());
}
public Object getAttribute(String name) {
return this.portletAttributes.get(name);
}
public Object getAttribute(String name, int scope) {
if (scope == PortletSession.PORTLET_SCOPE) {
return this.portletAttributes.get(name);
}
else if (scope == PortletSession.APPLICATION_SCOPE) {
return this.applicationAttributes.get(name);
}
return null;
}
public Enumeration<String> getAttributeNames() {
return Collections.enumeration(this.portletAttributes.keySet());
}
public Enumeration<String> getAttributeNames(int scope) {
if (scope == PortletSession.PORTLET_SCOPE) {
return Collections.enumeration(this.portletAttributes.keySet());
}
else if (scope == PortletSession.APPLICATION_SCOPE) {
return Collections.enumeration(this.applicationAttributes.keySet());
}
return null;
}
public long getCreationTime() {
return this.creationTime;
}
public String getId() {
return this.id;
}
public void access() {
this.lastAccessedTime = System.currentTimeMillis();
setNew(false);
}
public long getLastAccessedTime() {
return this.lastAccessedTime;
}
public int getMaxInactiveInterval() {
return this.maxInactiveInterval;
}
public void invalidate() {
this.invalid = true;
this.portletAttributes.clear();
this.applicationAttributes.clear();
}
public boolean isInvalid() {
return invalid;
}
public void setNew(boolean value) {
this.isNew = value;
}
public boolean isNew() {
return this.isNew;
}
public void removeAttribute(String name) {
this.portletAttributes.remove(name);
}
public void removeAttribute(String name, int scope) {
if (scope == PortletSession.PORTLET_SCOPE) {
this.portletAttributes.remove(name);
}
else if (scope == PortletSession.APPLICATION_SCOPE) {
this.applicationAttributes.remove(name);
}
}
public void setAttribute(String name, Object value) {
if (value != null) {
this.portletAttributes.put(name, value);
}
else {
this.portletAttributes.remove(name);
}
}
public void setAttribute(String name, Object value, int scope) {
if (scope == PortletSession.PORTLET_SCOPE) {
if (value != null) {
this.portletAttributes.put(name, value);
}
else {
this.portletAttributes.remove(name);
}
}
else if (scope == PortletSession.APPLICATION_SCOPE) {
if (value != null) {
this.applicationAttributes.put(name, value);
}
else {
this.applicationAttributes.remove(name);
}
}
}
public void setMaxInactiveInterval(int interval) {
this.maxInactiveInterval = interval;
}
public PortletContext getPortletContext() {
return portletContext;
}
}
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache 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.apache.org/licenses/LICENSE-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.springframework.mock.web.portlet;
import javax.portlet.PortalContext;
import javax.portlet.PortletContext;
import javax.portlet.PortletMode;
import javax.portlet.RenderRequest;
/**
* Mock implementation of the {@link javax.portlet.RenderRequest} interface.
*
* @author John A. Lewis
* @author Juergen Hoeller
* @since 2.0
*/
public class MockRenderRequest extends MockPortletRequest implements RenderRequest {
/**
* Create a new MockRenderRequest with a default {@link MockPortalContext}
* and a default {@link MockPortletContext}.
* @see MockPortalContext
* @see MockPortletContext
*/
public MockRenderRequest() {
super();
}
/**
* Create a new MockRenderRequest with a default {@link MockPortalContext}
* and a default {@link MockPortletContext}.
* @param portletMode the mode that the portlet runs in
*/
public MockRenderRequest(PortletMode portletMode) {
super();
setPortletMode(portletMode);
}
/**
* Create a new MockRenderRequest with a default {@link MockPortalContext}.
* @param portletContext the PortletContext that the request runs in
*/
public MockRenderRequest(PortletContext portletContext) {
super(portletContext);
}
/**
* Create a new MockRenderRequest.
* @param portalContext the PortletContext that the request runs in
* @param portletContext the PortletContext that the request runs in
*/
public MockRenderRequest(PortalContext portalContext, PortletContext portletContext) {
super(portalContext, portletContext);
}
}
<html>
<body>
A comprehensive set of Portlet API mock objects,
targeted at usage with Spring's web MVC framework.
Useful for testing web contexts and controllers.
<p>More convenient to use than dynamic mock objects
(<a href="http://www.easymock.org">EasyMock</a>) or
existing Portlet API mock objects.
</body>
</html>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册