001: // Copyright 2007 The Apache Software Foundation
002: //
003: // Licensed under the Apache License, Version 2.0 (the "License");
004: // you may not use this file except in compliance with the License.
005: // You may obtain a copy of the License at
006: //
007: // http://www.apache.org/licenses/LICENSE-2.0
008: //
009: // Unless required by applicable law or agreed to in writing, software
010: // distributed under the License is distributed on an "AS IS" BASIS,
011: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: // See the License for the specific language governing permissions and
013: // limitations under the License.
014:
015: package org.apache.tapestry.internal.services;
016:
017: import java.io.Serializable;
018:
019: import org.apache.tapestry.PropertyConduit;
020: import org.apache.tapestry.internal.bindings.PropBindingFactoryTest;
021: import org.apache.tapestry.internal.test.InternalBaseTestCase;
022: import org.apache.tapestry.ioc.internal.services.ClassFactoryImpl;
023: import org.apache.tapestry.ioc.services.ClassFab;
024: import org.apache.tapestry.ioc.services.ClassFactory;
025: import org.apache.tapestry.services.PropertyConduitSource;
026: import org.testng.annotations.AfterClass;
027: import org.testng.annotations.BeforeClass;
028: import org.testng.annotations.Test;
029:
030: /**
031: * Most of the testing occurs inside {@link PropBindingFactoryTest} (due to historical reasons).
032: */
033: public class PropertyConduitSourceImplTest extends InternalBaseTestCase {
034: private PropertyConduitSource _source;
035:
036: @BeforeClass
037: public void setup() {
038: _source = getObject(PropertyConduitSource.class, null);
039: }
040:
041: @AfterClass
042: public void cleanup() {
043: _source = null;
044: }
045:
046: @Test
047: public void question_dot_operator_for_object_type() {
048: PropertyConduit normal = _source.create(CompositeBean.class,
049: "simple.firstName");
050: PropertyConduit smart = _source.create(CompositeBean.class,
051: "simple?.firstName");
052:
053: CompositeBean bean = new CompositeBean();
054: bean.setSimple(null);
055:
056: try {
057: normal.get(bean);
058: unreachable();
059: } catch (NullPointerException ex) {
060: // Expected.
061: }
062:
063: assertNull(smart.get(bean));
064:
065: try {
066: normal.set(bean, "Howard");
067: unreachable();
068: } catch (NullPointerException ex) {
069: // Expected.
070: }
071:
072: // This will be a no-op due to the null property in the expression
073:
074: smart.set(bean, "Howard");
075: }
076:
077: /**
078: * Or call this the "Hibernate" case; Hibernate creates sub-classes of entity classes in its own
079: * class loader to do all sorts of proxying. This trips up Javassist.
080: */
081: @Test
082: public void handle_beans_from_unexpected_classloader()
083: throws Exception {
084: // First, create something that looks like a Hibernate proxy.
085:
086: ClassFactory factory = new ClassFactoryImpl();
087:
088: Class clazz = SimpleBean.class;
089:
090: ClassFab cf = factory.newClass(clazz.getName() + "$$Proxy",
091: clazz);
092:
093: cf.addInterface(Serializable.class);
094:
095: Class proxyClass = cf.createClass();
096:
097: SimpleBean simple = (SimpleBean) proxyClass.newInstance();
098:
099: assertTrue(simple instanceof Serializable);
100:
101: simple.setFirstName("Howard");
102:
103: PropertyConduit conduit = _source.create(proxyClass,
104: "firstName");
105:
106: assertEquals(conduit.get(simple), "Howard");
107: }
108:
109: }
|