• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.apache.velocity.test;
2 
3 /*
4  * Licensed to the Apache Software Foundation (ASF) under one
5  * or more contributor license agreements.  See the NOTICE file
6  * distributed with this work for additional information
7  * regarding copyright ownership.  The ASF licenses this file
8  * to you under the Apache License, Version 2.0 (the
9  * "License"); you may not use this file except in compliance
10  * with the License.  You may obtain a copy of the License at
11  *
12  *   http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17  * KIND, either express or implied.  See the License for the
18  * specific language governing permissions and limitations
19  * under the License.
20  */
21 
22 import junit.framework.Test;
23 import junit.framework.TestCase;
24 import junit.framework.TestSuite;
25 import org.apache.commons.io.IOUtils;
26 import org.apache.velocity.VelocityContext;
27 import org.apache.velocity.app.VelocityEngine;
28 import org.apache.velocity.test.misc.TestLogger;
29 import org.apache.velocity.util.introspection.IntrospectorCache;
30 
31 import java.io.ByteArrayOutputStream;
32 import java.io.InputStream;
33 import java.io.StringWriter;
34 
35 /**
36  * Tests if we can hand Velocity an arbitrary class for logging.
37  *
38  * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
39  * @version $Id$
40  */
41 public class ClassloaderChangeTestCase extends TestCase
42 {
43     private VelocityEngine ve = null;
44 	private TestLogger logger = null;
45 
46     private static String OUTPUT = "Hello From Foo";
47 
48     /**
49      * Default constructor.
50      */
ClassloaderChangeTestCase(String name)51     public ClassloaderChangeTestCase(String name)
52     {
53         super(name);
54     }
55 
56     @Override
setUp()57     public void setUp()
58             throws Exception
59     {
60         ve = new VelocityEngine();
61         logger = new TestLogger(false, true);
62         logger.setEnabledLevel(TestLogger.LOG_LEVEL_DEBUG);
63         ve.setProperty(VelocityEngine.RUNTIME_LOG_INSTANCE, logger);
64         ve.init();
65     }
66 
suite()67     public static Test suite ()
68     {
69         return new TestSuite(ClassloaderChangeTestCase.class);
70     }
71 
72     /**
73      * Runs the test.
74      */
testClassloaderChange()75     public void testClassloaderChange()
76         throws Exception
77     {
78         logger.on();
79 
80         VelocityContext vc = new VelocityContext();
81         Object foo = null;
82 
83         /*
84          *  first, we need a classloader to make our foo object
85          */
86 
87         TestClassloader cl = new TestClassloader();
88         Class<?> fooclass = cl.loadClass("Foo");
89         foo = fooclass.newInstance();
90 
91         /*
92          *  put it into the context
93          */
94         vc.put("foo", foo);
95 
96         /*
97          *  and render something that would use it
98          *  that will get it into the introspector cache
99          */
100         StringWriter writer = new StringWriter();
101         ve.evaluate( vc, writer, "test", "$foo.doIt()");
102 
103         /*
104          *  Check to make sure ok.  note the obvious
105          *  dependency on the Foo class...
106          */
107 
108         if ( !writer.toString().equals( OUTPUT ))
109         {
110             fail("Output from doIt() incorrect");
111         }
112 
113         /*
114          * and do it again :)
115          */
116         cl = new TestClassloader();
117         fooclass = cl.loadClass("Foo");
118         foo = fooclass.newInstance();
119 
120         vc.put("foo", foo);
121 
122         writer = new StringWriter();
123         ve.evaluate( vc, writer, "test", "$foo.doIt()");
124 
125         if ( !writer.toString().equals( OUTPUT ))
126         {
127             fail("Output from doIt() incorrect");
128         }
129 
130         if (!logger.getLog().contains(IntrospectorCache.CACHEDUMP_MSG))
131         {
132             fail("Didn't see introspector cache dump.");
133         }
134     }
135 
136     /**
137      *  Simple (real simple...) classloader that depends
138      *  on a Foo.class being located in the classloader
139      *  directory under test
140      */
141     public static class TestClassloader extends ClassLoader
142     {
143         private final static String testclass =
144             "classloader/Foo.class";
145 
146         private Class<?> fooClass = null;
147 
TestClassloader()148         public TestClassloader()
149                 throws Exception
150         {
151             ByteArrayOutputStream os = new ByteArrayOutputStream();
152             InputStream fis = getClass().getResourceAsStream("/" + testclass);
153             IOUtils.copy(fis, os);
154             fis.close();
155             os.close();
156 
157             byte[] barr = os.toByteArray();
158 
159             fooClass = defineClass("classloader.Foo", barr, 0, barr.length);
160         }
161 
162 
163         @Override
findClass(String name)164         public Class<?> findClass(String name)
165         {
166             return fooClass;
167         }
168     }
169 }
170