Mercurial > hg > Members > sugi > MessagePack-java
view src/main/java/org/msgpack/util/TemplatePrecompiler.java @ 0:cb825acd883a
first commit
author | sugi |
---|---|
date | Sat, 18 Oct 2014 15:06:15 +0900 |
parents | |
children |
line wrap: on
line source
// // MessagePack for Java // // Copyright (C) 2009 - 2013 FURUHASHI Sadayuki // // 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.msgpack.util; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Properties; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.tools.DiagnosticCollector; import javax.tools.JavaCompiler; import javax.tools.JavaFileManager; import javax.tools.JavaFileObject; import javax.tools.StandardLocation; import javax.tools.ToolProvider; import org.msgpack.template.TemplateRegistry; import org.msgpack.template.builder.JavassistTemplateBuilder; /** * This class is a template precompiler, which is used for saving templates that * <code>TemplateBuilder</code> generated. It saves templates as .class files. * Application enables to load the .class files and use templates. * */ public class TemplatePrecompiler { private static final Logger LOG = Logger.getLogger(TemplatePrecompiler.class.getName()); public static final String DEST = "msgpack.template.destdir"; public static final String DEFAULT_DEST = "."; public static void saveTemplates(final String[] classNames) throws IOException, ClassNotFoundException { // TODO #MN TemplateRegistry registry = new TemplateRegistry(null); List<String> ret = new ArrayList<String>(); for (String className : classNames) { matchClassNames(ret, className); } List<Class<?>> ret0 = toClass(ret); for (Class<?> c : ret0) { saveTemplateClass(registry, c); } } @SuppressWarnings("serial") private static void matchClassNames(List<String> ret, final String className) throws IOException { String packageName = className.substring(0, className.lastIndexOf('.')); String relativedName = className.substring( className.lastIndexOf('.') + 1, className.length()); String patName = relativedName.replace("*", "(\\w+)"); Pattern pat = Pattern.compile(patName); JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); JavaFileManager fm = compiler.getStandardFileManager( new DiagnosticCollector<JavaFileObject>(), null, null); HashSet<JavaFileObject.Kind> kind = new HashSet<JavaFileObject.Kind>() { { add(JavaFileObject.Kind.CLASS); } }; for (JavaFileObject f : fm.list(StandardLocation.PLATFORM_CLASS_PATH, packageName, kind, false)) { String relatived0 = f.getName(); String name0 = relatived0.substring(0, relatived0.length() - ".class".length()); Matcher m = pat.matcher(name0); if (m.matches()) { String name = packageName + '.' + name0; if (!ret.contains(name)) { ret.add(name); } } } } private static List<Class<?>> toClass(List<String> classNames) throws ClassNotFoundException { List<Class<?>> ret = new ArrayList<Class<?>>(classNames.size()); ClassLoader cl = TemplatePrecompiler.class.getClassLoader(); for (String className : classNames) { Class<?> c = cl.loadClass(className); ret.add(c); } return ret; } public static void saveTemplateClasses(TemplateRegistry registry, Class<?>[] targetClasses) throws IOException { for (Class<?> c : targetClasses) { saveTemplateClass(registry, c); } } public static void saveTemplateClass(TemplateRegistry registry, Class<?> targetClass) throws IOException { LOG.info("Saving template of " + targetClass.getName() + "..."); Properties props = System.getProperties(); String distDirName = getDirName(props, DEST, DEFAULT_DEST); if (targetClass.isEnum()) { throw new UnsupportedOperationException( "Not supported enum type yet: " + targetClass.getName()); } else { new JavassistTemplateBuilder(registry).writeTemplate(targetClass, distDirName); } LOG.info("Saved .class file of template class of " + targetClass.getName()); } public static boolean deleteTemplateClass(Class<?> targetClass) throws IOException { LOG.info("Deleting template of " + targetClass.getName() + "..."); Properties props = System.getProperties(); String distDirName = getDirName(props, DEST, DEFAULT_DEST); String targetClassName = targetClass.getName(); String targetClassFileName = targetClassName.replace('.', File.separatorChar) + "_$$_Template.class"; File targetFile = new File(distDirName + File.separatorChar + targetClassFileName); boolean deleted = false; if (!targetFile.isDirectory() && targetFile.exists()) { deleted = targetFile.delete(); } LOG.info("Deleted .class file of template class of " + targetClass.getName()); return deleted; } private static String getDirName(Properties props, String dirName, String defaultDirName) throws IOException { String dName = props.getProperty(dirName, defaultDirName); File d = new File(dName); if (!d.isDirectory() && !d.exists()) { throw new IOException("Directory not exists: " + dName); } return d.getAbsolutePath(); } public static void main(final String[] args) throws Exception { TemplatePrecompiler.saveTemplates(args); } }