Source Code Cross Referenced for TemplateClassLoader.java in  » Web-Framework » rife-1.6.1 » com » uwyn » rife » template » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Web Framework » rife 1.6.1 » com.uwyn.rife.template 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
003:         * Distributed under the terms of either:
004:         * - the common development and distribution license (CDDL), v1.0; or
005:         * - the GNU Lesser General Public License, v2.1 or later
006:         * $Id: TemplateClassLoader.java 3811 2007-06-25 15:06:16Z gbevin $
007:         */
008:        package com.uwyn.rife.template;
009:
010:        import com.tc.object.loaders.BytecodeProvider;
011:        import com.tc.object.loaders.NamedClassLoader;
012:        import com.uwyn.rife.config.RifeConfig;
013:        import com.uwyn.rife.resources.ResourceFinder;
014:        import com.uwyn.rife.template.exceptions.TemplateException;
015:        import com.uwyn.rife.tools.FileUtils;
016:        import com.uwyn.rife.tools.exceptions.FileUtilsErrorException;
017:        import java.io.File;
018:        import java.lang.reflect.InvocationTargetException;
019:        import java.lang.reflect.Method;
020:        import java.net.URL;
021:        import java.util.HashMap;
022:        import java.util.Map;
023:
024:        class TemplateClassLoader extends ClassLoader implements 
025:                NamedClassLoader, BytecodeProvider {
026:            private TemplateFactory mTemplateFactory = null;
027:
028:            // member vars required to support Terracotta
029:            private Map<String, byte[]> mBytecodeRepository = null;
030:            private String mClassLoaderName = "RIFE:TemplateClassLoader";
031:
032:            TemplateClassLoader(TemplateFactory templateFactory,
033:                    ClassLoader initiating) {
034:                super (initiating);
035:
036:                assert templateFactory != null;
037:                assert initiating != null;
038:
039:                // check for the presence of Terracotta by loading its ClassProcessorHelper class
040:                try {
041:                    Class classprocessor_helper_class = Class
042:                            .forName("com.tc.object.bytecode.hook.impl.ClassProcessorHelper");
043:                    if (classprocessor_helper_class != null) {
044:                        mBytecodeRepository = new HashMap<String, byte[]>();
045:
046:                        if (initiating instanceof  NamedClassLoader) {
047:                            NamedClassLoader namedParent = (NamedClassLoader) initiating;
048:                            mClassLoaderName = "Rife:Template:"
049:                                    + namedParent.__tc_getClassLoaderName();
050:
051:                            try {
052:                                Method method = classprocessor_helper_class
053:                                        .getDeclaredMethod(
054:                                                "registerGlobalLoader",
055:                                                new Class[] { NamedClassLoader.class });
056:                                method.invoke(null, new Object[] { this  });
057:                            } catch (Exception e) {
058:                                throw new RuntimeException(
059:                                        "Unable to register the template classloader '"
060:                                                + mClassLoaderName
061:                                                + "' with Terracotta.", e);
062:                            }
063:                        }
064:                    }
065:                } catch (ClassNotFoundException e) {
066:                    // this is OK, Terracotta is simply not present in the classpath
067:                }
068:
069:                mTemplateFactory = templateFactory;
070:            }
071:
072:            public byte[] __tc_getBytecodeForClass(final String className) {
073:                if (null == mBytecodeRepository) {
074:                    return null;
075:                }
076:
077:                synchronized (mBytecodeRepository) {
078:                    return mBytecodeRepository
079:                            .get(constructBytecodeRepositoryKey(className));
080:                }
081:            }
082:
083:            private String constructBytecodeRepositoryKey(String className) {
084:                return mClassLoaderName + '#' + className;
085:            }
086:
087:            public void __tc_setClassLoaderName(String name) {
088:                throw new UnsupportedOperationException(
089:                        "class loader name can not be modified for loader with name: "
090:                                + mClassLoaderName);
091:            }
092:
093:            public String __tc_getClassLoaderName() {
094:                return mClassLoaderName;
095:            }
096:
097:            protected Class loadClass(String classname, boolean resolve,
098:                    String encoding, TemplateTransformer transformer)
099:                    throws ClassNotFoundException {
100:                assert classname != null;
101:
102:                // see if this classloader has cached the class with the provided name
103:                Class c = findLoadedClass(classname);
104:
105:                // if an already loaded version was found, check whether it's outdated or not
106:                if (c != null) {
107:                    // if an already loaded version was found, check whether it's outdated or not
108:                    // this can only be Template classes since those are the only ones that are
109:                    // handled by this classloader
110:                    if (RifeConfig.Template.getAutoReload()) {
111:                        // if the template was modified, don't use the cached class
112:                        // otherwise, just take the previous template class
113:                        if (isTemplateModified(c, transformer)) {
114:                            TemplateClassLoader new_classloader = new TemplateClassLoader(
115:                                    mTemplateFactory, this .getParent());
116:                            // register the new classloader as the default templatefactory's
117:                            // classloader
118:                            mTemplateFactory.setClassLoader(new_classloader);
119:                            return new_classloader.loadClass(classname,
120:                                    resolve, encoding, transformer);
121:                        }
122:                    }
123:                }
124:                // try to obtain the class in another way
125:                else {
126:                    // try to obtain it from the parent classloader or from the system classloader
127:                    ClassLoader parent = getParent();
128:                    if (parent != null) {
129:                        try {
130:                            // the parent is never a TemplateClassLoader, it's always the
131:                            // class that instantiated the initial TemplateClassLoader
132:                            // thus, the encoding doesn't need to be passed on further
133:                            c = parent.loadClass(classname);
134:
135:                            // if templates are reloaded automatically, check if a corresponding
136:                            // class was found in the parent classloader. If that class came from a jar
137:                            // file, make sure it's returned immediately and don't try to recompile it
138:                            if (c != null
139:                                    && RifeConfig.Template.getAutoReload()) {
140:                                URL resource = parent.getResource(classname
141:                                        .replace('.', '/')
142:                                        + ".class");
143:                                if (resource != null
144:                                        && resource.getPath().indexOf('!') != -1) {
145:                                    // resolve the class if it's needed
146:                                    if (resolve) {
147:                                        resolveClass(c);
148:                                    }
149:
150:                                    return c;
151:                                }
152:                            }
153:                        } catch (ClassNotFoundException e) {
154:                            c = null;
155:                        }
156:                    }
157:
158:                    if (null == c) {
159:                        try {
160:                            c = findSystemClass(classname);
161:                        } catch (ClassNotFoundException e) {
162:                            c = null;
163:                        }
164:                    }
165:
166:                    // load template class files in class path
167:                    if (c != null && !classname.startsWith("java.")
168:                            && !classname.startsWith("javax.")
169:                            && !classname.startsWith("sun.")
170:                            && Template.class.isAssignableFrom(c)) {
171:                        // verify if the template in the classpath has been updated
172:                        if (RifeConfig.Template.getAutoReload()
173:                                && isTemplateModified(c, transformer)) {
174:                            c = null;
175:                        }
176:                    }
177:
178:                    if (null == c) {
179:                        // intern the classname to get a synchronization lock monitor
180:                        // that is specific for the current class that is loaded and
181:                        // that will not lock up the classloading of all other classes
182:                        // by for instance synchronizing on this classloader
183:                        classname = classname.intern();
184:                        synchronized (classname) {
185:                            // make sure that the class has not been defined in the
186:                            // meantime, otherwise defining it again will trigger an
187:                            // exception;
188:                            // reuse the existing class if it has already been defined
189:                            c = findLoadedClass(classname);
190:                            if (null == c) {
191:                                byte[] raw = compileTemplate(classname,
192:                                        encoding, transformer);
193:
194:                                // only use the bytecode repository when is has been initialized because Terracotta is available
195:                                if (mBytecodeRepository != null) {
196:                                    synchronized (mBytecodeRepository) {
197:                                        String key = constructBytecodeRepositoryKey(classname);
198:                                        mBytecodeRepository.put(key, raw);
199:                                    }
200:                                }
201:
202:                                // define the bytes of the class for this classloader
203:                                c = defineClass(classname, raw, 0, raw.length);
204:                            }
205:                        }
206:                    }
207:                }
208:
209:                // resolve the class if it's needed
210:                if (resolve) {
211:                    resolveClass(c);
212:                }
213:
214:                assert c != null;
215:
216:                return c;
217:            }
218:
219:            private byte[] compileTemplate(String classname, String encoding,
220:                    TemplateTransformer transformer)
221:                    throws ClassNotFoundException {
222:                assert classname != null;
223:
224:                // try to resolve the classname as a template name by resolving the template
225:                URL template_url = mTemplateFactory.getParser().resolve(
226:                        classname);
227:                if (null == template_url) {
228:                    throw new ClassNotFoundException(
229:                            "Couldn't resolve template: '" + classname + "'.");
230:                }
231:
232:                // prepare the template with all the information that's needed to be able to identify
233:                // this template uniquely
234:                Parsed template_parsed = mTemplateFactory.getParser().prepare(
235:                        classname, template_url);
236:
237:                // parse the template
238:                try {
239:                    mTemplateFactory.getParser().parse(template_parsed,
240:                            encoding, transformer);
241:                } catch (TemplateException e) {
242:                    throw new ClassNotFoundException(
243:                            "Error while parsing template: '" + classname
244:                                    + "'.", e);
245:                }
246:
247:                byte[] byte_code = template_parsed.getByteCode();
248:                if (RifeConfig.Template.getGenerateClasses()) {
249:                    // get the package and the short classname of the template
250:                    String template_package = template_parsed.getPackage();
251:                    template_package = template_package.replace('.',
252:                            File.separatorChar);
253:                    String template_classname = template_parsed.getClassName();
254:
255:                    // setup everything to perform the conversion of the template to java sources
256:                    // and to compile it into a java class
257:                    String generation_path = RifeConfig.Template
258:                            .getGenerationPath()
259:                            + File.separatorChar;
260:                    String packagedir = generation_path + template_package;
261:                    String filename_class = packagedir + File.separator
262:                            + template_classname + ".class";
263:                    File file_packagedir = new File(packagedir);
264:                    File file_class = new File(filename_class);
265:
266:                    // prepare the package directory
267:                    if (!file_packagedir.exists()) {
268:                        if (!file_packagedir.mkdirs()) {
269:                            throw new ClassNotFoundException(
270:                                    "Couldn't create the template package directory : '"
271:                                            + packagedir + "'.");
272:                        }
273:                    } else if (!file_packagedir.isDirectory()) {
274:                        throw new ClassNotFoundException(
275:                                "The template package directory '" + packagedir
276:                                        + "' exists but is not a directory.");
277:                    } else if (!file_packagedir.canWrite()) {
278:                        throw new ClassNotFoundException(
279:                                "The template package directory '" + packagedir
280:                                        + "' is not writable.");
281:                    }
282:
283:                    try {
284:                        FileUtils.writeBytes(byte_code, file_class);
285:                    } catch (FileUtilsErrorException e) {
286:                        throw new ClassNotFoundException(
287:                                "Error while writing the contents of the template class file '"
288:                                        + classname + "'.", e);
289:                    }
290:                }
291:                return byte_code;
292:            }
293:
294:            private boolean isTemplateModified(Class c,
295:                    TemplateTransformer transformer) {
296:                assert c != null;
297:
298:                boolean is_modified = true;
299:                Method is_modified_method = null;
300:                String modification_state = null;
301:                if (transformer != null) {
302:                    modification_state = transformer.getState();
303:                }
304:                try {
305:                    is_modified_method = c.getMethod("isModified", new Class[] {
306:                            ResourceFinder.class, String.class });
307:                    is_modified = (Boolean) is_modified_method.invoke(null,
308:                            new Object[] {
309:                                    mTemplateFactory.getResourceFinder(),
310:                                    modification_state });
311:                } catch (NoSuchMethodException e) {
312:                    // do nothing, template will be considered as outdated
313:                } catch (SecurityException e) {
314:                    // do nothing, template will be considered as outdated
315:                } catch (IllegalAccessException e) {
316:                    // do nothing, template will be considered as outdated
317:                } catch (IllegalArgumentException e) {
318:                    // do nothing, template will be considered as outdated
319:                } catch (InvocationTargetException e) {
320:                    // do nothing, template will be considered as outdated
321:                }
322:
323:                return is_modified;
324:            }
325:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.