Browse Source
git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@472 50f2f4bb-b051-0410-bef5-90022cba6387pull/1/head
53 changed files with 5876 additions and 6 deletions
@ -0,0 +1,182 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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"; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,849 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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,131 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -0,0 +1 @@
|
||||
page=MeineSeite |
||||
Binary file not shown.
@ -0,0 +1,227 @@
@@ -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 @@
@@ -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