eliminated svn:externals in favor of localized copies of shared artifacts
git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@472 50f2f4bb-b051-0410-bef5-90022cba6387
This commit is contained in:
parent
4049170b79
commit
e1965dea0f
|
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
* 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<?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>
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<?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>
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
<?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>
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,345 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,234 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<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>
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* 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++;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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 {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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";
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* 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 {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* 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);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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 {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* 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";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,849 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.Principal;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Vector;
|
||||
|
||||
import javax.servlet.RequestDispatcher;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletInputStream;
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Mock implementation of the {@link javax.servlet.http.HttpServletRequest}
|
||||
* interface. Supports the Servlet 2.4 API level.
|
||||
*
|
||||
* <p>Used for testing the web framework; also useful for testing
|
||||
* application controllers.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @author Rod Johnson
|
||||
* @author Rick Evans
|
||||
* @author Mark Fisher
|
||||
* @since 1.0.2
|
||||
*/
|
||||
public class MockHttpServletRequest implements HttpServletRequest {
|
||||
|
||||
/**
|
||||
* The default protocol: 'http'.
|
||||
*/
|
||||
public static final String DEFAULT_PROTOCOL = "http";
|
||||
|
||||
/**
|
||||
* The default server address: '127.0.0.1'.
|
||||
*/
|
||||
public static final String DEFAULT_SERVER_ADDR = "127.0.0.1";
|
||||
|
||||
/**
|
||||
* The default server name: 'localhost'.
|
||||
*/
|
||||
public static final String DEFAULT_SERVER_NAME = "localhost";
|
||||
|
||||
/**
|
||||
* The default server port: '80'.
|
||||
*/
|
||||
public static final int DEFAULT_SERVER_PORT = 80;
|
||||
|
||||
/**
|
||||
* The default remote address: '127.0.0.1'.
|
||||
*/
|
||||
public static final String DEFAULT_REMOTE_ADDR = "127.0.0.1";
|
||||
|
||||
/**
|
||||
* The default remote host: 'localhost'.
|
||||
*/
|
||||
public static final String DEFAULT_REMOTE_HOST = "localhost";
|
||||
|
||||
|
||||
private boolean active = true;
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// ServletRequest properties
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
private final Hashtable attributes = new Hashtable();
|
||||
|
||||
private String characterEncoding;
|
||||
|
||||
private byte[] content;
|
||||
|
||||
private String contentType;
|
||||
|
||||
private final Map<String, String[]> parameters = new LinkedHashMap<String, String[]>(16);
|
||||
|
||||
private String protocol = DEFAULT_PROTOCOL;
|
||||
|
||||
private String scheme = DEFAULT_PROTOCOL;
|
||||
|
||||
private String serverName = DEFAULT_SERVER_NAME;
|
||||
|
||||
private int serverPort = DEFAULT_SERVER_PORT;
|
||||
|
||||
private String remoteAddr = DEFAULT_REMOTE_ADDR;
|
||||
|
||||
private String remoteHost = DEFAULT_REMOTE_HOST;
|
||||
|
||||
/** List of locales in descending order */
|
||||
private final Vector locales = new Vector();
|
||||
|
||||
private boolean secure = false;
|
||||
|
||||
private final ServletContext servletContext;
|
||||
|
||||
private int remotePort = DEFAULT_SERVER_PORT;
|
||||
|
||||
private String localName = DEFAULT_SERVER_NAME;
|
||||
|
||||
private String localAddr = DEFAULT_SERVER_ADDR;
|
||||
|
||||
private int localPort = DEFAULT_SERVER_PORT;
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// HttpServletRequest properties
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
private String authType;
|
||||
|
||||
private Cookie[] cookies;
|
||||
|
||||
/**
|
||||
* The key is the lowercase header name; the value is a {@link HeaderValueHolder} object.
|
||||
*/
|
||||
private final Hashtable headers = new Hashtable();
|
||||
|
||||
private String method;
|
||||
|
||||
private String pathInfo;
|
||||
|
||||
private String contextPath = "";
|
||||
|
||||
private String queryString;
|
||||
|
||||
private String remoteUser;
|
||||
|
||||
private final Set userRoles = new HashSet();
|
||||
|
||||
private Principal userPrincipal;
|
||||
|
||||
private String requestURI;
|
||||
|
||||
private String servletPath = "";
|
||||
|
||||
private HttpSession session;
|
||||
|
||||
private boolean requestedSessionIdValid = true;
|
||||
|
||||
private boolean requestedSessionIdFromCookie = true;
|
||||
|
||||
private boolean requestedSessionIdFromURL = false;
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Constructors
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create a new MockHttpServletRequest with a default
|
||||
* {@link MockServletContext}.
|
||||
* @see MockServletContext
|
||||
*/
|
||||
public MockHttpServletRequest() {
|
||||
this(null, "", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new MockHttpServletRequest with a default
|
||||
* {@link MockServletContext}.
|
||||
* @param method the request method (may be <code>null</code>)
|
||||
* @param requestURI the request URI (may be <code>null</code>)
|
||||
* @see #setMethod
|
||||
* @see #setRequestURI
|
||||
* @see MockServletContext
|
||||
*/
|
||||
public MockHttpServletRequest(String method, String requestURI) {
|
||||
this(null, method, requestURI);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new MockHttpServletRequest.
|
||||
* @param servletContext the ServletContext that the request runs in
|
||||
* (may be <code>null</code> to use a default MockServletContext)
|
||||
* @see MockServletContext
|
||||
*/
|
||||
public MockHttpServletRequest(ServletContext servletContext) {
|
||||
this(servletContext, "", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new MockHttpServletRequest.
|
||||
* @param servletContext the ServletContext that the request runs in
|
||||
* (may be <code>null</code> to use a default MockServletContext)
|
||||
* @param method the request method (may be <code>null</code>)
|
||||
* @param requestURI the request URI (may be <code>null</code>)
|
||||
* @see #setMethod
|
||||
* @see #setRequestURI
|
||||
* @see MockServletContext
|
||||
*/
|
||||
public MockHttpServletRequest(ServletContext servletContext, String method, String requestURI) {
|
||||
this.servletContext = (servletContext != null ? servletContext : new MockServletContext());
|
||||
this.method = method;
|
||||
this.requestURI = requestURI;
|
||||
this.locales.add(Locale.ENGLISH);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Lifecycle methods
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Return the ServletContext that this request is associated with.
|
||||
* (Not available in the standard HttpServletRequest interface for some reason.)
|
||||
*/
|
||||
public ServletContext getServletContext() {
|
||||
return this.servletContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether this request is still active (that is, not completed yet).
|
||||
*/
|
||||
public boolean isActive() {
|
||||
return this.active;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark this request as completed, keeping its state.
|
||||
*/
|
||||
public void close() {
|
||||
this.active = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate this request, clearing its state.
|
||||
*/
|
||||
public void invalidate() {
|
||||
close();
|
||||
clearAttributes();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// ServletRequest interface
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
public Object getAttribute(String name) {
|
||||
checkActive();
|
||||
return this.attributes.get(name);
|
||||
}
|
||||
|
||||
public Enumeration getAttributeNames() {
|
||||
checkActive();
|
||||
return this.attributes.keys();
|
||||
}
|
||||
|
||||
public String getCharacterEncoding() {
|
||||
return this.characterEncoding;
|
||||
}
|
||||
|
||||
public void setCharacterEncoding(String characterEncoding) {
|
||||
this.characterEncoding = characterEncoding;
|
||||
}
|
||||
|
||||
public void setContent(byte[] content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public int getContentLength() {
|
||||
return (this.content != null ? this.content.length : -1);
|
||||
}
|
||||
|
||||
public void setContentType(String contentType) {
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
||||
public String getContentType() {
|
||||
return this.contentType;
|
||||
}
|
||||
|
||||
public ServletInputStream getInputStream() {
|
||||
if (this.content != null) {
|
||||
return new DelegatingServletInputStream(new ByteArrayInputStream(this.content));
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a single value for the specified HTTP parameter.
|
||||
* <p>If there are already one or more values registered for the given
|
||||
* parameter name, they will be replaced.
|
||||
*/
|
||||
public void setParameter(String name, String value) {
|
||||
setParameter(name, new String[] {value});
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an array of values for the specified HTTP parameter.
|
||||
* <p>If there are already one or more values registered for the given
|
||||
* parameter name, they will be replaced.
|
||||
*/
|
||||
public void setParameter(String name, String[] values) {
|
||||
Assert.notNull(name, "Parameter name must not be null");
|
||||
this.parameters.put(name, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets all provided parameters <emphasis>replacing</emphasis> any
|
||||
* existing values for the provided parameter names. To add without
|
||||
* replacing existing values, use {@link #addParameters(java.util.Map)}.
|
||||
*/
|
||||
public void setParameters(Map params) {
|
||||
Assert.notNull(params, "Parameter map must not be null");
|
||||
for (Object key : params.keySet()) {
|
||||
Assert.isInstanceOf(String.class, key,
|
||||
"Parameter map key must be of type [" + String.class.getName() + "]");
|
||||
Object value = params.get(key);
|
||||
if (value instanceof String) {
|
||||
this.setParameter((String) key, (String) value);
|
||||
}
|
||||
else if (value instanceof String[]) {
|
||||
this.setParameter((String) key, (String[]) value);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException(
|
||||
"Parameter map value must be single value " + " or array of type [" + String.class.getName() +
|
||||
"]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a single value for the specified HTTP parameter.
|
||||
* <p>If there are already one or more values registered for the given
|
||||
* parameter name, the given value will be added to the end of the list.
|
||||
*/
|
||||
public void addParameter(String name, String value) {
|
||||
addParameter(name, new String[] {value});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an array of values for the specified HTTP parameter.
|
||||
* <p>If there are already one or more values registered for the given
|
||||
* parameter name, the given values will be added to the end of the list.
|
||||
*/
|
||||
public void addParameter(String name, String[] values) {
|
||||
Assert.notNull(name, "Parameter name must not be null");
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all provided parameters <emphasis>without</emphasis> replacing
|
||||
* any existing values. To replace existing values, use
|
||||
* {@link #setParameters(java.util.Map)}.
|
||||
*/
|
||||
public void addParameters(Map params) {
|
||||
Assert.notNull(params, "Parameter map must not be null");
|
||||
for (Object key : params.keySet()) {
|
||||
Assert.isInstanceOf(String.class, key,
|
||||
"Parameter map key must be of type [" + String.class.getName() + "]");
|
||||
Object value = params.get(key);
|
||||
if (value instanceof String) {
|
||||
this.addParameter((String) key, (String) value);
|
||||
}
|
||||
else if (value instanceof String[]) {
|
||||
this.addParameter((String) key, (String[]) value);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException("Parameter map value must be single value " +
|
||||
" or array of type [" + String.class.getName() + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove already registered values for the specified HTTP parameter, if any.
|
||||
*/
|
||||
public void removeParameter(String name) {
|
||||
Assert.notNull(name, "Parameter name must not be null");
|
||||
this.parameters.remove(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all existing parameters.
|
||||
*/
|
||||
public void removeAllParameters() {
|
||||
this.parameters.clear();
|
||||
}
|
||||
|
||||
public String getParameter(String name) {
|
||||
Assert.notNull(name, "Parameter name must not be null");
|
||||
String[] arr = this.parameters.get(name);
|
||||
return (arr != null && arr.length > 0 ? arr[0] : null);
|
||||
}
|
||||
|
||||
public Enumeration getParameterNames() {
|
||||
return Collections.enumeration(this.parameters.keySet());
|
||||
}
|
||||
|
||||
public String[] getParameterValues(String name) {
|
||||
Assert.notNull(name, "Parameter name must not be null");
|
||||
return this.parameters.get(name);
|
||||
}
|
||||
|
||||
public Map getParameterMap() {
|
||||
return Collections.unmodifiableMap(this.parameters);
|
||||
}
|
||||
|
||||
public void setProtocol(String protocol) {
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
public String getProtocol() {
|
||||
return this.protocol;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 void setRemoteAddr(String remoteAddr) {
|
||||
this.remoteAddr = remoteAddr;
|
||||
}
|
||||
|
||||
public String getRemoteAddr() {
|
||||
return this.remoteAddr;
|
||||
}
|
||||
|
||||
public void setRemoteHost(String remoteHost) {
|
||||
this.remoteHost = remoteHost;
|
||||
}
|
||||
|
||||
public String getRemoteHost() {
|
||||
return this.remoteHost;
|
||||
}
|
||||
|
||||
public void setAttribute(String name, Object value) {
|
||||
checkActive();
|
||||
Assert.notNull(name, "Attribute name must not be null");
|
||||
if (value != null) {
|
||||
this.attributes.put(name, value);
|
||||
}
|
||||
else {
|
||||
this.attributes.remove(name);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeAttribute(String name) {
|
||||
checkActive();
|
||||
Assert.notNull(name, "Attribute name must not be null");
|
||||
this.attributes.remove(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all of this request's attributes.
|
||||
*/
|
||||
public void clearAttributes() {
|
||||
this.attributes.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new preferred locale, before any existing locales.
|
||||
*/
|
||||
public void addPreferredLocale(Locale locale) {
|
||||
Assert.notNull(locale, "Locale must not be null");
|
||||
this.locales.add(0, locale);
|
||||
}
|
||||
|
||||
public Locale getLocale() {
|
||||
return (Locale) this.locales.get(0);
|
||||
}
|
||||
|
||||
public Enumeration getLocales() {
|
||||
return this.locales.elements();
|
||||
}
|
||||
|
||||
public void setSecure(boolean secure) {
|
||||
this.secure = secure;
|
||||
}
|
||||
|
||||
public boolean isSecure() {
|
||||
return this.secure;
|
||||
}
|
||||
|
||||
public RequestDispatcher getRequestDispatcher(String path) {
|
||||
return new MockRequestDispatcher(path);
|
||||
}
|
||||
|
||||
public String getRealPath(String path) {
|
||||
return this.servletContext.getRealPath(path);
|
||||
}
|
||||
|
||||
public void setRemotePort(int remotePort) {
|
||||
this.remotePort = remotePort;
|
||||
}
|
||||
|
||||
public int getRemotePort() {
|
||||
return this.remotePort;
|
||||
}
|
||||
|
||||
public void setLocalName(String localName) {
|
||||
this.localName = localName;
|
||||
}
|
||||
|
||||
public String getLocalName() {
|
||||
return this.localName;
|
||||
}
|
||||
|
||||
public void setLocalAddr(String localAddr) {
|
||||
this.localAddr = localAddr;
|
||||
}
|
||||
|
||||
public String getLocalAddr() {
|
||||
return this.localAddr;
|
||||
}
|
||||
|
||||
public void setLocalPort(int localPort) {
|
||||
this.localPort = localPort;
|
||||
}
|
||||
|
||||
public int getLocalPort() {
|
||||
return this.localPort;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// HttpServletRequest interface
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
public void setAuthType(String authType) {
|
||||
this.authType = authType;
|
||||
}
|
||||
|
||||
public String getAuthType() {
|
||||
return this.authType;
|
||||
}
|
||||
|
||||
public void setCookies(Cookie[] cookies) {
|
||||
this.cookies = cookies;
|
||||
}
|
||||
|
||||
public Cookie[] getCookies() {
|
||||
return this.cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a header entry for the given name.
|
||||
* <p>If there was no entry for that header name before,
|
||||
* the value will be used as-is. In case of an existing entry,
|
||||
* a String array will be created, adding the given value (more
|
||||
* specifically, its toString representation) as further element.
|
||||
* <p>Multiple values can only be stored as list of Strings,
|
||||
* following the Servlet spec (see <code>getHeaders</code> accessor).
|
||||
* As alternative to repeated <code>addHeader</code> calls for
|
||||
* individual elements, you can use a single call with an entire
|
||||
* array or Collection of values as parameter.
|
||||
* @see #getHeaderNames
|
||||
* @see #getHeader
|
||||
* @see #getHeaders
|
||||
* @see #getDateHeader
|
||||
* @see #getIntHeader
|
||||
*/
|
||||
public void addHeader(String name, Object value) {
|
||||
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
|
||||
Assert.notNull(value, "Header value must not be null");
|
||||
if (header == null) {
|
||||
header = new HeaderValueHolder();
|
||||
this.headers.put(name, header);
|
||||
}
|
||||
if (value instanceof Collection) {
|
||||
header.addValues((Collection) value);
|
||||
}
|
||||
else if (value.getClass().isArray()) {
|
||||
header.addValueArray(value);
|
||||
}
|
||||
else {
|
||||
header.addValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
public long getDateHeader(String name) {
|
||||
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
|
||||
Object value = (header != null ? header.getValue() : null);
|
||||
if (value instanceof Date) {
|
||||
return ((Date) value).getTime();
|
||||
}
|
||||
else if (value instanceof Number) {
|
||||
return ((Number) value).longValue();
|
||||
}
|
||||
else if (value != null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Value for header '" + name + "' is neither a Date nor a Number: " + value);
|
||||
}
|
||||
else {
|
||||
return -1L;
|
||||
}
|
||||
}
|
||||
|
||||
public String getHeader(String name) {
|
||||
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
|
||||
return (header != null ? header.getValue().toString() : null);
|
||||
}
|
||||
|
||||
public Enumeration getHeaders(String name) {
|
||||
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
|
||||
return Collections.enumeration(header != null ? header.getValues() : Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
public Enumeration getHeaderNames() {
|
||||
return this.headers.keys();
|
||||
}
|
||||
|
||||
public int getIntHeader(String name) {
|
||||
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
|
||||
Object value = (header != null ? header.getValue() : null);
|
||||
if (value instanceof Number) {
|
||||
return ((Number) value).intValue();
|
||||
}
|
||||
else if (value instanceof String) {
|
||||
return Integer.parseInt((String) value);
|
||||
}
|
||||
else if (value != null) {
|
||||
throw new NumberFormatException("Value for header '" + name + "' is not a Number: " + value);
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public void setMethod(String method) {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
public String getMethod() {
|
||||
return this.method;
|
||||
}
|
||||
|
||||
public void setPathInfo(String pathInfo) {
|
||||
this.pathInfo = pathInfo;
|
||||
}
|
||||
|
||||
public String getPathInfo() {
|
||||
return this.pathInfo;
|
||||
}
|
||||
|
||||
public String getPathTranslated() {
|
||||
return (this.pathInfo != null ? getRealPath(this.pathInfo) : null);
|
||||
}
|
||||
|
||||
public void setContextPath(String contextPath) {
|
||||
this.contextPath = contextPath;
|
||||
}
|
||||
|
||||
public String getContextPath() {
|
||||
return this.contextPath;
|
||||
}
|
||||
|
||||
public void setQueryString(String queryString) {
|
||||
this.queryString = queryString;
|
||||
}
|
||||
|
||||
public String getQueryString() {
|
||||
return this.queryString;
|
||||
}
|
||||
|
||||
public void setRemoteUser(String remoteUser) {
|
||||
this.remoteUser = remoteUser;
|
||||
}
|
||||
|
||||
public String getRemoteUser() {
|
||||
return this.remoteUser;
|
||||
}
|
||||
|
||||
public void addUserRole(String role) {
|
||||
this.userRoles.add(role);
|
||||
}
|
||||
|
||||
public boolean isUserInRole(String role) {
|
||||
return this.userRoles.contains(role);
|
||||
}
|
||||
|
||||
public void setUserPrincipal(Principal userPrincipal) {
|
||||
this.userPrincipal = userPrincipal;
|
||||
}
|
||||
|
||||
public Principal getUserPrincipal() {
|
||||
return this.userPrincipal;
|
||||
}
|
||||
|
||||
public String getRequestedSessionId() {
|
||||
HttpSession session = getSession();
|
||||
return (session != null ? session.getId() : null);
|
||||
}
|
||||
|
||||
public void setRequestURI(String requestURI) {
|
||||
this.requestURI = requestURI;
|
||||
}
|
||||
|
||||
public String getRequestURI() {
|
||||
return this.requestURI;
|
||||
}
|
||||
|
||||
public StringBuffer getRequestURL() {
|
||||
StringBuffer url = new StringBuffer(this.scheme);
|
||||
url.append("://").append(this.serverName).append(':').append(this.serverPort);
|
||||
url.append(getRequestURI());
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setServletPath(String servletPath) {
|
||||
this.servletPath = servletPath;
|
||||
}
|
||||
|
||||
public String getServletPath() {
|
||||
return this.servletPath;
|
||||
}
|
||||
|
||||
public void setSession(HttpSession session) {
|
||||
this.session = session;
|
||||
if (session instanceof MockHttpSession) {
|
||||
MockHttpSession mockSession = ((MockHttpSession) session);
|
||||
mockSession.access();
|
||||
}
|
||||
}
|
||||
|
||||
public HttpSession getSession(boolean create) {
|
||||
checkActive();
|
||||
// Reset session if invalidated.
|
||||
if (this.session instanceof MockHttpSession && ((MockHttpSession) this.session).isInvalid()) {
|
||||
this.session = null;
|
||||
}
|
||||
// Create new session if necessary.
|
||||
if (this.session == null && create) {
|
||||
this.session = new MockHttpSession(this.servletContext);
|
||||
}
|
||||
return this.session;
|
||||
}
|
||||
|
||||
public HttpSession getSession() {
|
||||
return getSession(true);
|
||||
}
|
||||
|
||||
public void setRequestedSessionIdValid(boolean requestedSessionIdValid) {
|
||||
this.requestedSessionIdValid = requestedSessionIdValid;
|
||||
}
|
||||
|
||||
public boolean isRequestedSessionIdValid() {
|
||||
return this.requestedSessionIdValid;
|
||||
}
|
||||
|
||||
public void setRequestedSessionIdFromCookie(boolean requestedSessionIdFromCookie) {
|
||||
this.requestedSessionIdFromCookie = requestedSessionIdFromCookie;
|
||||
}
|
||||
|
||||
public boolean isRequestedSessionIdFromCookie() {
|
||||
return this.requestedSessionIdFromCookie;
|
||||
}
|
||||
|
||||
public void setRequestedSessionIdFromURL(boolean requestedSessionIdFromURL) {
|
||||
this.requestedSessionIdFromURL = requestedSessionIdFromURL;
|
||||
}
|
||||
|
||||
public boolean isRequestedSessionIdFromURL() {
|
||||
return this.requestedSessionIdFromURL;
|
||||
}
|
||||
|
||||
public boolean isRequestedSessionIdFromUrl() {
|
||||
return isRequestedSessionIdFromURL();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,345 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,234 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* 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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,462 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* 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 + "]");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
* 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.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.portlet.PortalContext;
|
||||
import javax.portlet.PortletMode;
|
||||
import javax.portlet.PortletModeException;
|
||||
import javax.portlet.PortletSecurityException;
|
||||
import javax.portlet.PortletURL;
|
||||
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.PortletURL} interface.
|
||||
*
|
||||
* @author John A. Lewis
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.0
|
||||
*/
|
||||
public class MockPortletURL implements PortletURL {
|
||||
|
||||
public static final String URL_TYPE_RENDER = "render";
|
||||
|
||||
public static final String URL_TYPE_ACTION = "action";
|
||||
|
||||
private static final String ENCODING = "UTF-8";
|
||||
|
||||
|
||||
private final PortalContext portalContext;
|
||||
|
||||
private final String urlType;
|
||||
|
||||
private WindowState windowState;
|
||||
|
||||
private PortletMode portletMode;
|
||||
|
||||
private final Map<String, String[]> parameters = new LinkedHashMap<String, String[]>();
|
||||
|
||||
private boolean secure = false;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new MockPortletURL for the given URL type.
|
||||
* @param portalContext the PortalContext defining the supported
|
||||
* PortletModes and WindowStates
|
||||
* @param urlType the URL type, for example "render" or "action"
|
||||
* @see #URL_TYPE_RENDER
|
||||
* @see #URL_TYPE_ACTION
|
||||
*/
|
||||
public MockPortletURL(PortalContext portalContext, String urlType) {
|
||||
Assert.notNull(portalContext, "PortalContext is required");
|
||||
this.portalContext = portalContext;
|
||||
this.urlType = urlType;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// PortletURL methods
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
public void setWindowState(WindowState windowState) throws WindowStateException {
|
||||
if (!CollectionUtils.contains(this.portalContext.getSupportedWindowStates(), windowState)) {
|
||||
throw new WindowStateException("WindowState not supported", windowState);
|
||||
}
|
||||
this.windowState = windowState;
|
||||
}
|
||||
|
||||
public void setPortletMode(PortletMode portletMode) throws PortletModeException {
|
||||
if (!CollectionUtils.contains(this.portalContext.getSupportedPortletModes(), portletMode)) {
|
||||
throw new PortletModeException("PortletMode not supported", portletMode);
|
||||
}
|
||||
this.portletMode = portletMode;
|
||||
}
|
||||
|
||||
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 setParameters(Map parameters) {
|
||||
Assert.notNull(parameters, "Parameters Map must not be null");
|
||||
this.parameters.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.parameters.put((String) entry.getKey(), (String[]) entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public Set<String> getParameterNames() {
|
||||
return this.parameters.keySet();
|
||||
}
|
||||
|
||||
public String getParameter(String name) {
|
||||
String[] arr = this.parameters.get(name);
|
||||
return (arr != null && arr.length > 0 ? arr[0] : null);
|
||||
}
|
||||
|
||||
public String[] getParameterValues(String name) {
|
||||
return this.parameters.get(name);
|
||||
}
|
||||
|
||||
public Map<String, String[]> getParameterMap() {
|
||||
return Collections.unmodifiableMap(this.parameters);
|
||||
}
|
||||
|
||||
public void setSecure(boolean secure) throws PortletSecurityException {
|
||||
this.secure = secure;
|
||||
}
|
||||
|
||||
public boolean isSecure() {
|
||||
return this.secure;
|
||||
}
|
||||
|
||||
|
||||
private String encodeParameter(String name, String value) {
|
||||
try {
|
||||
return URLEncoder.encode(name, ENCODING) + "=" + URLEncoder.encode(value, ENCODING);
|
||||
}
|
||||
catch (UnsupportedEncodingException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private String encodeParameter(String name, String[] values) {
|
||||
try {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0, n = values.length; i < n; i++) {
|
||||
sb.append((i > 0 ? ";" : "") +
|
||||
URLEncoder.encode(name, ENCODING) + "=" +
|
||||
URLEncoder.encode(values[i], ENCODING));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
catch (UnsupportedEncodingException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(encodeParameter("urlType", this.urlType));
|
||||
if (this.windowState != null) {
|
||||
sb.append(";").append(encodeParameter("windowState", this.windowState.toString()));
|
||||
}
|
||||
if (this.portletMode != null) {
|
||||
sb.append(";").append(encodeParameter("portletMode", this.portletMode.toString()));
|
||||
}
|
||||
for (Map.Entry<String, String[]> entry : this.parameters.entrySet()) {
|
||||
sb.append(";").append(encodeParameter("param_" + entry.getKey(), entry.getValue()));
|
||||
}
|
||||
return (this.secure ? "https:" : "http:") +
|
||||
"//localhost/mockportlet?" + sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
* 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.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.io.Writer;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.portlet.PortalContext;
|
||||
import javax.portlet.PortletURL;
|
||||
import javax.portlet.RenderResponse;
|
||||
|
||||
import org.springframework.web.util.WebUtils;
|
||||
|
||||
/**
|
||||
* Mock implementation of the {@link javax.portlet.RenderResponse} interface.
|
||||
*
|
||||
* @author John A. Lewis
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.0
|
||||
*/
|
||||
public class MockRenderResponse extends MockPortletResponse implements RenderResponse {
|
||||
|
||||
private String contentType;
|
||||
|
||||
private String namespace = "MockPortlet";
|
||||
|
||||
private String title;
|
||||
|
||||
private String characterEncoding = WebUtils.DEFAULT_CHARACTER_ENCODING;
|
||||
|
||||
private PrintWriter writer;
|
||||
|
||||
private Locale locale = Locale.getDefault();
|
||||
|
||||
private int bufferSize = 4096;
|
||||
|
||||
private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
|
||||
private boolean committed;
|
||||
|
||||
private String includedUrl;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new MockRenderResponse with a default {@link MockPortalContext}.
|
||||
* @see MockPortalContext
|
||||
*/
|
||||
public MockRenderResponse() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new MockRenderResponse.
|
||||
* @param portalContext the PortalContext defining the supported
|
||||
* PortletModes and WindowStates
|
||||
*/
|
||||
public MockRenderResponse(PortalContext portalContext) {
|
||||
super(portalContext);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// RenderResponse methods
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
public String getContentType() {
|
||||
return this.contentType;
|
||||
}
|
||||
|
||||
public PortletURL createRenderURL() {
|
||||
PortletURL url = new MockPortletURL(getPortalContext(), MockPortletURL.URL_TYPE_RENDER);
|
||||
return url;
|
||||
}
|
||||
|
||||
public PortletURL createActionURL() {
|
||||
PortletURL url = new MockPortletURL(getPortalContext(), MockPortletURL.URL_TYPE_ACTION);
|
||||
return url;
|
||||
}
|
||||
|
||||
public String getNamespace() {
|
||||
return this.namespace;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setContentType(String contentType) {
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
||||
public void setCharacterEncoding(String characterEncoding) {
|
||||
this.characterEncoding = characterEncoding;
|
||||
}
|
||||
|
||||
public String getCharacterEncoding() {
|
||||
return this.characterEncoding;
|
||||
}
|
||||
|
||||
public PrintWriter getWriter() throws UnsupportedEncodingException {
|
||||
if (this.writer == null) {
|
||||
Writer targetWriter = (this.characterEncoding != null
|
||||
? new OutputStreamWriter(this.outputStream, this.characterEncoding)
|
||||
: new OutputStreamWriter(this.outputStream));
|
||||
this.writer = new PrintWriter(targetWriter);
|
||||
}
|
||||
return this.writer;
|
||||
}
|
||||
|
||||
public byte[] getContentAsByteArray() {
|
||||
flushBuffer();
|
||||
return this.outputStream.toByteArray();
|
||||
}
|
||||
|
||||
public String getContentAsString() throws UnsupportedEncodingException {
|
||||
flushBuffer();
|
||||
return (this.characterEncoding != null)
|
||||
? this.outputStream.toString(this.characterEncoding)
|
||||
: this.outputStream.toString();
|
||||
}
|
||||
|
||||
public void setLocale(Locale locale) {
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
public Locale getLocale() {
|
||||
return this.locale;
|
||||
}
|
||||
|
||||
public void setBufferSize(int bufferSize) {
|
||||
this.bufferSize = bufferSize;
|
||||
}
|
||||
|
||||
public int getBufferSize() {
|
||||
return this.bufferSize;
|
||||
}
|
||||
|
||||
public void flushBuffer() {
|
||||
if (this.writer != null) {
|
||||
this.writer.flush();
|
||||
}
|
||||
if (this.outputStream != null) {
|
||||
try {
|
||||
this.outputStream.flush();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new IllegalStateException("Could not flush OutputStream: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
this.committed = true;
|
||||
}
|
||||
|
||||
public void resetBuffer() {
|
||||
if (this.committed) {
|
||||
throw new IllegalStateException("Cannot reset buffer - response is already committed");
|
||||
}
|
||||
this.outputStream.reset();
|
||||
}
|
||||
|
||||
public void setCommitted(boolean committed) {
|
||||
this.committed = committed;
|
||||
}
|
||||
|
||||
public boolean isCommitted() {
|
||||
return this.committed;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
resetBuffer();
|
||||
this.characterEncoding = null;
|
||||
this.contentType = null;
|
||||
this.locale = null;
|
||||
}
|
||||
|
||||
public OutputStream getPortletOutputStream() throws IOException {
|
||||
return this.outputStream;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Methods for MockPortletRequestDispatcher
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
public void setIncludedUrl(String includedUrl) {
|
||||
this.includedUrl = includedUrl;
|
||||
}
|
||||
|
||||
public String getIncludedUrl() {
|
||||
return includedUrl;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<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>
|
||||
Binary file not shown.
|
|
@ -0,0 +1,185 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Created using JasperAssistant (http://www.jasperassistant.com) -->
|
||||
<!DOCTYPE jasperReport PUBLIC "-//JasperReports//DTD Report Design//EN" "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">
|
||||
|
||||
<jasperReport name="DataSourceReport" pageWidth="595" pageHeight="842" columnWidth="515" leftMargin="40" rightMargin="40" topMargin="50" bottomMargin="50">
|
||||
<reportFont name="Arial_Normal" isDefault="true" fontName="Arial" size="12" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
|
||||
<reportFont name="Arial_Bold" isDefault="false" fontName="Arial" size="12" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
|
||||
<reportFont name="Arial_Italic" isDefault="false" fontName="Arial" size="12" isBold="false" isItalic="true" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Oblique" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
|
||||
<parameter name="ReportTitle" class="java.lang.String">
|
||||
</parameter>
|
||||
<parameter name="DataFile" class="java.lang.String">
|
||||
</parameter>
|
||||
<field name="id" class="java.lang.Integer">
|
||||
</field>
|
||||
<field name="name" class="java.lang.String">
|
||||
</field>
|
||||
<field name="street" class="java.lang.String">
|
||||
</field>
|
||||
<field name="city" class="java.lang.String">
|
||||
</field>
|
||||
<variable name="CityNumber" class="java.lang.Integer" resetType="Group" resetGroup="CityGroup" calculation="System">
|
||||
<initialValueExpression><![CDATA[($V{CityNumber} != null)?(new Integer($V{CityNumber}.intValue() + 1)):(new Integer(1))]]></initialValueExpression>
|
||||
</variable>
|
||||
<group name="CityGroup" minHeightToStartNewPage="60">
|
||||
<groupExpression><![CDATA[$F{city}]]></groupExpression>
|
||||
<groupHeader>
|
||||
<band height="20">
|
||||
<rectangle>
|
||||
<reportElement x="0" y="4" width="515" height="15" forecolor="#c0c0c0" backcolor="#c0c0c0"/>
|
||||
<graphicElement/>
|
||||
</rectangle>
|
||||
<textField>
|
||||
<reportElement mode="Opaque" x="0" y="4" width="515" height="15" backcolor="#c0c0c0"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[" " + String.valueOf($V{CityNumber}) + ". " + String.valueOf($F{city})]]></textFieldExpression>
|
||||
</textField>
|
||||
<line>
|
||||
<reportElement x="0" y="19" width="515" height="1"/>
|
||||
<graphicElement/>
|
||||
</line>
|
||||
</band>
|
||||
</groupHeader>
|
||||
<groupFooter>
|
||||
<band height="20">
|
||||
<line>
|
||||
<reportElement x="0" y="-1" width="515" height="1"/>
|
||||
<graphicElement/>
|
||||
</line>
|
||||
<staticText>
|
||||
<reportElement x="400" y="1" width="60" height="15"/>
|
||||
<textElement textAlignment="Right">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Count :]]></text>
|
||||
</staticText>
|
||||
<textField>
|
||||
<reportElement x="460" y="1" width="30" height="15"/>
|
||||
<textElement textAlignment="Right">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.Integer"><![CDATA[$V{CityGroup_COUNT}]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</groupFooter>
|
||||
</group>
|
||||
<title>
|
||||
<band height="70">
|
||||
<line>
|
||||
<reportElement x="0" y="0" width="515" height="1"/>
|
||||
<graphicElement/>
|
||||
</line>
|
||||
<textField isBlankWhenNull="true">
|
||||
<reportElement x="0" y="10" width="515" height="30"/>
|
||||
<textElement textAlignment="Center">
|
||||
<font reportFont="Arial_Normal" size="22"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[$P{ReportTitle}]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField isBlankWhenNull="true">
|
||||
<reportElement x="0" y="40" width="515" height="20"/>
|
||||
<textElement textAlignment="Center">
|
||||
<font reportFont="Arial_Normal" size="14"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[$P{DataFile}]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</title>
|
||||
<pageHeader>
|
||||
<band height="20">
|
||||
<rectangle>
|
||||
<reportElement x="0" y="5" width="515" height="15" forecolor="#333333" backcolor="#333333"/>
|
||||
<graphicElement/>
|
||||
</rectangle>
|
||||
<staticText>
|
||||
<reportElement mode="Opaque" x="0" y="5" width="55" height="15" forecolor="#ffffff" backcolor="#333333"/>
|
||||
<textElement textAlignment="Center">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[ID]]></text>
|
||||
</staticText>
|
||||
<staticText>
|
||||
<reportElement mode="Opaque" x="55" y="5" width="205" height="15" forecolor="#ffffff" backcolor="#333333"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Name]]></text>
|
||||
</staticText>
|
||||
<staticText>
|
||||
<reportElement mode="Opaque" x="260" y="5" width="255" height="15" forecolor="#ffffff" backcolor="#333333"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Street]]></text>
|
||||
</staticText>
|
||||
</band>
|
||||
</pageHeader>
|
||||
<detail>
|
||||
<band height="20">
|
||||
<textField>
|
||||
<reportElement x="0" y="4" width="50" height="15"/>
|
||||
<textElement textAlignment="Right"/>
|
||||
<textFieldExpression class="java.lang.Integer"><![CDATA[$F{id}]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField isStretchWithOverflow="true">
|
||||
<reportElement positionType="Float" x="55" y="4" width="200" height="15"/>
|
||||
<textElement/>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[$F{name}]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField isStretchWithOverflow="true">
|
||||
<reportElement positionType="Float" x="260" y="4" width="255" height="15"/>
|
||||
<textElement/>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[$F{street}]]></textFieldExpression>
|
||||
</textField>
|
||||
<line>
|
||||
<reportElement positionType="Float" x="0" y="19" width="515" height="1" forecolor="#808080"/>
|
||||
<graphicElement/>
|
||||
</line>
|
||||
</band>
|
||||
</detail>
|
||||
<pageFooter>
|
||||
<band height="40">
|
||||
<line>
|
||||
<reportElement x="0" y="10" width="515" height="1"/>
|
||||
<graphicElement/>
|
||||
</line>
|
||||
<textField>
|
||||
<reportElement x="200" y="20" width="80" height="15"/>
|
||||
<textElement textAlignment="Right"/>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[$R{page} + " " + String.valueOf($V{PAGE_NUMBER}) + " of"]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField evaluationTime="Report">
|
||||
<reportElement x="280" y="20" width="75" height="15"/>
|
||||
<textElement/>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[" " + String.valueOf($V{PAGE_NUMBER})]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</pageFooter>
|
||||
<lastPageFooter>
|
||||
<band height="60">
|
||||
<textField>
|
||||
<reportElement x="0" y="10" width="515" height="15"/>
|
||||
<textElement textAlignment="Center"/>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA["There were " +
|
||||
String.valueOf($V{REPORT_COUNT}) +
|
||||
" address records on this report."]]></textFieldExpression>
|
||||
</textField>
|
||||
<line>
|
||||
<reportElement x="0" y="30" width="515" height="1"/>
|
||||
<graphicElement/>
|
||||
</line>
|
||||
<textField>
|
||||
<reportElement x="200" y="40" width="80" height="15"/>
|
||||
<textElement textAlignment="Right"/>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[$R{page} + " " + String.valueOf($V{PAGE_NUMBER}) + " of"]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField evaluationTime="Report">
|
||||
<reportElement x="280" y="40" width="75" height="15"/>
|
||||
<textElement/>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[" " + String.valueOf($V{PAGE_NUMBER})]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</lastPageFooter>
|
||||
</jasperReport>
|
||||
|
|
@ -0,0 +1 @@
|
|||
page=MeineSeite
|
||||
Binary file not shown.
|
|
@ -0,0 +1,227 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Created using JasperAssistant (http://www.jasperassistant.com) -->
|
||||
<!DOCTYPE jasperReport PUBLIC "-//JasperReports//DTD Report Design//EN" "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">
|
||||
|
||||
<jasperReport name="ProductReport" columnCount="2" pageWidth="325" pageHeight="842" columnWidth="160" columnSpacing="5" leftMargin="0" rightMargin="0" topMargin="0" bottomMargin="0">
|
||||
<reportFont name="Arial_Normal" isDefault="true" fontName="Arial" size="8" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
|
||||
<reportFont name="Arial_Bold" isDefault="false" fontName="Arial" size="8" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
|
||||
<reportFont name="Arial_Italic" isDefault="false" fontName="Arial" size="8" isBold="false" isItalic="true" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Oblique" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
|
||||
<parameter name="City" class="java.lang.String"/>
|
||||
<field name="id" class="java.lang.Integer">
|
||||
</field>
|
||||
<field name="name" class="java.lang.String">
|
||||
</field>
|
||||
<field name="quantity" class="java.lang.Float">
|
||||
</field>
|
||||
<field name="price" class="java.lang.Float">
|
||||
</field>
|
||||
<variable name="QuantityProductSum" class="java.lang.Float" resetType="Group" resetGroup="ProductGroup" calculation="Sum">
|
||||
<variableExpression><![CDATA[$F{quantity}]]></variableExpression>
|
||||
</variable>
|
||||
<variable name="PriceProductSum" class="java.lang.Float" resetType="Group" resetGroup="ProductGroup" calculation="Sum">
|
||||
<variableExpression><![CDATA[$F{price}]]></variableExpression>
|
||||
</variable>
|
||||
<variable name="QuantitySum" class="java.lang.Float" calculation="Sum">
|
||||
<variableExpression><![CDATA[$F{quantity}]]></variableExpression>
|
||||
</variable>
|
||||
<variable name="PriceSum" class="java.lang.Float" calculation="Sum">
|
||||
<variableExpression><![CDATA[$F{price}]]></variableExpression>
|
||||
</variable>
|
||||
<variable name="ProductCount" class="java.lang.Integer" resetType="Group" resetGroup="ProductGroup" calculation="System">
|
||||
<initialValueExpression><![CDATA[($V{ProductCount} != null)?(new Integer($V{ProductCount}.intValue() + 1)):(new Integer(1))]]></initialValueExpression>
|
||||
</variable>
|
||||
<group name="ProductGroup">
|
||||
<groupExpression><![CDATA[$F{id}]]></groupExpression>
|
||||
<groupHeader>
|
||||
<band height="14">
|
||||
<textField>
|
||||
<reportElement x="0" y="2" width="15" height="10"/>
|
||||
<textElement textAlignment="Right"/>
|
||||
<textFieldExpression class="java.lang.Integer"><![CDATA[$F{id}]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField isStretchWithOverflow="true">
|
||||
<reportElement positionType="Float" x="20" y="2" width="80" height="10"/>
|
||||
<textElement/>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[$F{name}]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField isStretchWithOverflow="true" evaluationTime="Group" evaluationGroup="ProductGroup" pattern="#0">
|
||||
<reportElement positionType="Float" x="105" y="2" width="20" height="10"/>
|
||||
<textElement textAlignment="Right"/>
|
||||
<textFieldExpression class="java.lang.Float"><![CDATA[$V{QuantityProductSum}]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField isStretchWithOverflow="true" evaluationTime="Group" evaluationGroup="ProductGroup" pattern="#0.00">
|
||||
<reportElement positionType="Float" x="130" y="2" width="30" height="10"/>
|
||||
<textElement textAlignment="Right"/>
|
||||
<textFieldExpression class="java.lang.Float"><![CDATA[$V{PriceProductSum}]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</groupHeader>
|
||||
<groupFooter>
|
||||
<band>
|
||||
</band>
|
||||
</groupFooter>
|
||||
</group>
|
||||
<title>
|
||||
<band height="14">
|
||||
<staticText>
|
||||
<reportElement x="0" y="2" width="60" height="10"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Italic"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Title]]></text>
|
||||
</staticText>
|
||||
<textField>
|
||||
<reportElement x="0" y="2" width="325" height="10"/>
|
||||
<textElement textAlignment="Center">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA["Products ordered by people in " + $P{City}]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</title>
|
||||
<pageHeader>
|
||||
<band height="14">
|
||||
<rectangle>
|
||||
<reportElement mode="Transparent" x="0" y="2" width="325" height="10" forecolor="#808000"/>
|
||||
<graphicElement pen="Thin"/>
|
||||
</rectangle>
|
||||
<staticText>
|
||||
<reportElement x="0" y="2" width="60" height="10" forecolor="#808000"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Italic"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Page Header]]></text>
|
||||
</staticText>
|
||||
</band>
|
||||
</pageHeader>
|
||||
<columnHeader>
|
||||
<band height="14">
|
||||
<rectangle>
|
||||
<reportElement x="0" y="2" width="160" height="10" forecolor="#ffff99" backcolor="#ffff99"/>
|
||||
<graphicElement/>
|
||||
</rectangle>
|
||||
<staticText>
|
||||
<reportElement mode="Opaque" x="0" y="2" width="20" height="10" backcolor="#ffff99"/>
|
||||
<textElement textAlignment="Center">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[ID]]></text>
|
||||
</staticText>
|
||||
<staticText>
|
||||
<reportElement mode="Opaque" x="20" y="2" width="85" height="10" backcolor="#ffff99"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Name]]></text>
|
||||
</staticText>
|
||||
<staticText>
|
||||
<reportElement mode="Opaque" x="105" y="2" width="20" height="10" backcolor="#ffff99"/>
|
||||
<textElement textAlignment="Right">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Qty]]></text>
|
||||
</staticText>
|
||||
<staticText>
|
||||
<reportElement mode="Opaque" x="125" y="2" width="35" height="10" backcolor="#ffff99"/>
|
||||
<textElement textAlignment="Right">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Price]]></text>
|
||||
</staticText>
|
||||
</band>
|
||||
</columnHeader>
|
||||
<columnFooter>
|
||||
<band height="14">
|
||||
<line>
|
||||
<reportElement x="0" y="1" width="160" height="1"/>
|
||||
<graphicElement pen="Thin"/>
|
||||
</line>
|
||||
<staticText>
|
||||
<reportElement x="0" y="2" width="60" height="10"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Italic"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Column Footer]]></text>
|
||||
</staticText>
|
||||
<staticText>
|
||||
<reportElement x="70" y="2" width="30" height="10"/>
|
||||
<textElement textAlignment="Right">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Total :]]></text>
|
||||
</staticText>
|
||||
<textField pattern="#0">
|
||||
<reportElement x="105" y="2" width="20" height="10"/>
|
||||
<textElement textAlignment="Right">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.Float"><![CDATA[$V{QuantitySum}]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField pattern="#0.00">
|
||||
<reportElement x="130" y="2" width="30" height="10"/>
|
||||
<textElement textAlignment="Right">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.Float"><![CDATA[$V{PriceSum}]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</columnFooter>
|
||||
<pageFooter>
|
||||
<band height="14">
|
||||
<rectangle>
|
||||
<reportElement mode="Transparent" x="0" y="2" width="325" height="10" forecolor="#808000"/>
|
||||
<graphicElement pen="Thin"/>
|
||||
</rectangle>
|
||||
<staticText>
|
||||
<reportElement x="0" y="2" width="60" height="10" forecolor="#808000"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Italic"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Page Footer]]></text>
|
||||
</staticText>
|
||||
<textField>
|
||||
<reportElement x="150" y="2" width="100" height="10" forecolor="#808000"/>
|
||||
<textElement textAlignment="Right">
|
||||
<font reportFont="Arial_Italic"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA["Page " + String.valueOf($V{PAGE_NUMBER}) + " of "]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField evaluationTime="Report">
|
||||
<reportElement x="250" y="2" width="50" height="10" forecolor="#808000"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Italic"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.Integer"><![CDATA[$V{PAGE_NUMBER}]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</pageFooter>
|
||||
<summary>
|
||||
<band height="14">
|
||||
<rectangle>
|
||||
<reportElement x="0" y="2" width="325" height="10" forecolor="#808000" backcolor="#808000"/>
|
||||
<graphicElement pen="Thin"/>
|
||||
</rectangle>
|
||||
<staticText>
|
||||
<reportElement mode="Opaque" x="0" y="2" width="230" height="10" backcolor="#808000"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Italic"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Summary]]></text>
|
||||
</staticText>
|
||||
<staticText>
|
||||
<reportElement mode="Opaque" x="230" y="2" width="55" height="10" backcolor="#808000"/>
|
||||
<textElement textAlignment="Right">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Count :]]></text>
|
||||
</staticText>
|
||||
<textField pattern="#0">
|
||||
<reportElement mode="Opaque" x="285" y="2" width="40" height="10" backcolor="#808000"/>
|
||||
<textElement textAlignment="Right">
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.Integer"><![CDATA[$V{ProductCount}]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</summary>
|
||||
</jasperReport>
|
||||
Binary file not shown.
|
|
@ -0,0 +1,103 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Created using JasperAssistant (http://www.jasperassistant.com) -->
|
||||
<!DOCTYPE jasperReport PUBLIC "-//JasperReports//DTD Report Design//EN" "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">
|
||||
|
||||
<jasperReport name="MasterReport" pageWidth="595" pageHeight="842" columnWidth="515" leftMargin="40" rightMargin="40" topMargin="50" bottomMargin="50">
|
||||
<reportFont name="Arial_Normal" isDefault="true" fontName="Arial" size="12" isBold="false" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
|
||||
<reportFont name="Arial_Bold" isDefault="false" fontName="Arial" size="12" isBold="true" isItalic="false" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Bold" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
|
||||
<reportFont name="Arial_Italic" isDefault="false" fontName="Arial" size="12" isBold="false" isItalic="true" isUnderline="false" isStrikeThrough="false" pdfFontName="Helvetica-Oblique" pdfEncoding="Cp1252" isPdfEmbedded="false"/>
|
||||
<parameter name="ProductsSubReport" class="net.sf.jasperreports.engine.JasperReport"/>
|
||||
<parameter name="SubReportData" class="net.sf.jasperreports.engine.JRDataSource"/>
|
||||
<field name="city" class="java.lang.String">
|
||||
</field>
|
||||
<title>
|
||||
<band height="50">
|
||||
<line>
|
||||
<reportElement x="0" y="0" width="515" height="1"/>
|
||||
<graphicElement/>
|
||||
</line>
|
||||
<staticText>
|
||||
<reportElement x="0" y="10" width="515" height="30"/>
|
||||
<textElement textAlignment="Center">
|
||||
<font reportFont="Arial_Normal" size="22"/>
|
||||
</textElement>
|
||||
<text><![CDATA[Master Report]]></text>
|
||||
</staticText>
|
||||
</band>
|
||||
</title>
|
||||
<pageHeader>
|
||||
<band height="21">
|
||||
<rectangle>
|
||||
<reportElement x="0" y="5" width="515" height="15" backcolor="#333333"/>
|
||||
<graphicElement pen="None"/>
|
||||
</rectangle>
|
||||
<staticText>
|
||||
<reportElement mode="Opaque" x="0" y="5" width="515" height="15" forecolor="#ffffff" backcolor="#333333"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[City List]]></text>
|
||||
</staticText>
|
||||
<line>
|
||||
<reportElement x="0" y="20" width="515" height="1"/>
|
||||
<graphicElement/>
|
||||
</line>
|
||||
</band>
|
||||
</pageHeader>
|
||||
<detail>
|
||||
<band height="50">
|
||||
<textField>
|
||||
<reportElement x="5" y="5" width="100" height="15" isPrintWhenDetailOverflows="true"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[$F{city}]]></textFieldExpression>
|
||||
</textField>
|
||||
<staticText>
|
||||
<reportElement isPrintRepeatedValues="false" x="110" y="5" width="100" height="15" isPrintWhenDetailOverflows="true"/>
|
||||
<textElement>
|
||||
<font reportFont="Arial_Bold"/>
|
||||
</textElement>
|
||||
<text><![CDATA[(continued)]]></text>
|
||||
</staticText>
|
||||
<line>
|
||||
<reportElement x="0" y="20" width="515" height="1" isPrintWhenDetailOverflows="true"/>
|
||||
<graphicElement/>
|
||||
</line>
|
||||
<subreport>
|
||||
<reportElement isPrintRepeatedValues="false" x="5" y="25" width="325" height="20" isRemoveLineWhenBlank="true" backcolor="#ffcc99"/>
|
||||
<subreportParameter name="City">
|
||||
<subreportParameterExpression><![CDATA[$F{city}]]></subreportParameterExpression>
|
||||
</subreportParameter>
|
||||
<dataSourceExpression><![CDATA[$P{SubReportData}]]></dataSourceExpression>
|
||||
<subreportExpression class="net.sf.jasperreports.engine.JasperReport"><![CDATA[$P{ProductsSubReport}]]></subreportExpression>
|
||||
</subreport>
|
||||
<!--<subreport>
|
||||
<reportElement positionType="Float" x="335" y="25" width="175" height="20" isRemoveLineWhenBlank="true" backcolor="#99ccff"/>
|
||||
<subreportParameter name="City">
|
||||
<subreportParameterExpression><![CDATA[$F{City}]]></subreportParameterExpression>
|
||||
</subreportParameter>
|
||||
<connectionExpression><![CDATA[$P{REPORT_CONNECTION}]]></connectionExpression>
|
||||
<subreportExpression class="java.lang.String"><![CDATA["AddressReport.jasper"]]></subreportExpression>
|
||||
</subreport> -->
|
||||
</band>
|
||||
</detail>
|
||||
<pageFooter>
|
||||
<band height="40">
|
||||
<line>
|
||||
<reportElement x="0" y="10" width="515" height="1"/>
|
||||
<graphicElement/>
|
||||
</line>
|
||||
<textField>
|
||||
<reportElement x="200" y="20" width="80" height="15"/>
|
||||
<textElement textAlignment="Right"/>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA["Page " + String.valueOf($V{PAGE_NUMBER}) + " of"]]></textFieldExpression>
|
||||
</textField>
|
||||
<textField evaluationTime="Report">
|
||||
<reportElement x="280" y="20" width="75" height="15"/>
|
||||
<textElement/>
|
||||
<textFieldExpression class="java.lang.String"><![CDATA[" " + String.valueOf($V{PAGE_NUMBER})]]></textFieldExpression>
|
||||
</textField>
|
||||
</band>
|
||||
</pageFooter>
|
||||
</jasperReport>
|
||||
Loading…
Reference in New Issue