001: package org.apache.velocity.test;
002:
003: /*
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021:
022: import java.io.File;
023: import java.io.FileInputStream;
024: import java.io.StringWriter;
025:
026: import junit.framework.Test;
027: import junit.framework.TestCase;
028: import junit.framework.TestSuite;
029:
030: import org.apache.velocity.VelocityContext;
031: import org.apache.velocity.app.VelocityEngine;
032: import org.apache.velocity.runtime.RuntimeServices;
033: import org.apache.velocity.runtime.log.LogChute;
034: import org.apache.velocity.util.introspection.Introspector;
035:
036: /**
037: * Tests if we can hand Velocity an arbitrary class for logging.
038: *
039: * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
040: * @version $Id: ClassloaderChangeTestCase.java 463298 2006-10-12 16:10:32Z henning $
041: */
042: public class ClassloaderChangeTestCase extends TestCase implements
043: LogChute {
044: private VelocityEngine ve = null;
045: private boolean sawCacheDump = false;
046:
047: private static String OUTPUT = "Hello From Foo";
048:
049: /**
050: * Default constructor.
051: */
052: public ClassloaderChangeTestCase(String name) {
053: super (name);
054: }
055:
056: public void setUp() throws Exception {
057: ve = new VelocityEngine();
058: ve.setProperty(VelocityEngine.RUNTIME_LOG_LOGSYSTEM, this );
059: ve.init();
060: }
061:
062: public void init(RuntimeServices rs) {
063: // do nothing with it
064: }
065:
066: public static Test suite() {
067: return new TestSuite(ClassloaderChangeTestCase.class);
068: }
069:
070: /**
071: * Runs the test.
072: */
073: public void testClassloaderChange() throws Exception {
074: sawCacheDump = false;
075:
076: VelocityContext vc = new VelocityContext();
077: Object foo = null;
078:
079: /*
080: * first, we need a classloader to make our foo object
081: */
082:
083: TestClassloader cl = new TestClassloader();
084: Class fooclass = cl.loadClass("Foo");
085: foo = fooclass.newInstance();
086:
087: /*
088: * put it into the context
089: */
090: vc.put("foo", foo);
091:
092: /*
093: * and render something that would use it
094: * that will get it into the introspector cache
095: */
096: StringWriter writer = new StringWriter();
097: ve.evaluate(vc, writer, "test", "$foo.doIt()");
098:
099: /*
100: * Check to make sure ok. note the obvious
101: * dependency on the Foo class...
102: */
103:
104: if (!writer.toString().equals(OUTPUT)) {
105: fail("Output from doIt() incorrect");
106: }
107:
108: /*
109: * and do it again :)
110: */
111: cl = new TestClassloader();
112: fooclass = cl.loadClass("Foo");
113: foo = fooclass.newInstance();
114:
115: vc.put("foo", foo);
116:
117: writer = new StringWriter();
118: ve.evaluate(vc, writer, "test", "$foo.doIt()");
119:
120: if (!writer.toString().equals(OUTPUT)) {
121: fail("Output from doIt() incorrect");
122: }
123:
124: if (!sawCacheDump) {
125: fail("Didn't see introspector cache dump.");
126: }
127: }
128:
129: /**
130: * method to catch Velocity log messages. When we
131: * see the introspector dump message, then set the flag
132: */
133: public void log(int level, String message) {
134: if (message.equals(Introspector.CACHEDUMP_MSG)) {
135: sawCacheDump = true;
136: }
137: }
138:
139: /**
140: * method to catch Velocity log messages. When we
141: * see the introspector dump message, then set the flag
142: */
143: public void log(int level, String message, Throwable t) {
144: // ignore the Throwable for this test
145: log(level, message);
146: }
147:
148: public boolean isLevelEnabled(int level) {
149: return true;
150: }
151: }
152:
153: /**
154: * Simple (real simple...) classloader that depends
155: * on a Foo.class being located in the classloader
156: * directory under test
157: */
158: class TestClassloader extends ClassLoader {
159: private final static String testclass = "test/classloader/Foo.class";
160:
161: private Class fooClass = null;
162:
163: public TestClassloader() throws Exception {
164: File f = new File(testclass);
165:
166: byte[] barr = new byte[(int) f.length()];
167:
168: FileInputStream fis = new FileInputStream(f);
169: fis.read(barr);
170: fis.close();
171:
172: fooClass = defineClass("Foo", barr, 0, barr.length);
173: }
174:
175: public Class findClass(String name) {
176: return fooClass;
177: }
178: }
|