0
|
1 //
|
|
2 // MessagePack for Java
|
|
3 //
|
|
4 // Copyright (C) 2009 - 2013 FURUHASHI Sadayuki
|
|
5 //
|
|
6 // Licensed under the Apache License, Version 2.0 (the "License");
|
|
7 // you may not use this file except in compliance with the License.
|
|
8 // You may obtain a copy of the License at
|
|
9 //
|
|
10 // http://www.apache.org/licenses/LICENSE-2.0
|
|
11 //
|
|
12 // Unless required by applicable law or agreed to in writing, software
|
|
13 // distributed under the License is distributed on an "AS IS" BASIS,
|
|
14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15 // See the License for the specific language governing permissions and
|
|
16 // limitations under the License.
|
|
17 //
|
|
18 package org.msgpack.util;
|
|
19
|
|
20 import java.io.File;
|
|
21 import java.io.IOException;
|
|
22 import java.util.ArrayList;
|
|
23 import java.util.HashSet;
|
|
24 import java.util.List;
|
|
25 import java.util.Properties;
|
|
26 import java.util.logging.Logger;
|
|
27 import java.util.regex.Matcher;
|
|
28 import java.util.regex.Pattern;
|
|
29
|
|
30 import javax.tools.DiagnosticCollector;
|
|
31 import javax.tools.JavaCompiler;
|
|
32 import javax.tools.JavaFileManager;
|
|
33 import javax.tools.JavaFileObject;
|
|
34 import javax.tools.StandardLocation;
|
|
35 import javax.tools.ToolProvider;
|
|
36
|
|
37 import org.msgpack.template.TemplateRegistry;
|
|
38 import org.msgpack.template.builder.JavassistTemplateBuilder;
|
|
39
|
|
40 /**
|
|
41 * This class is a template precompiler, which is used for saving templates that
|
|
42 * <code>TemplateBuilder</code> generated. It saves templates as .class files.
|
|
43 * Application enables to load the .class files and use templates.
|
|
44 *
|
|
45 */
|
|
46 public class TemplatePrecompiler {
|
|
47
|
|
48 private static final Logger LOG = Logger.getLogger(TemplatePrecompiler.class.getName());
|
|
49
|
|
50 public static final String DEST = "msgpack.template.destdir";
|
|
51
|
|
52 public static final String DEFAULT_DEST = ".";
|
|
53
|
|
54 public static void saveTemplates(final String[] classNames)
|
|
55 throws IOException, ClassNotFoundException {
|
|
56 // TODO #MN
|
|
57 TemplateRegistry registry = new TemplateRegistry(null);
|
|
58 List<String> ret = new ArrayList<String>();
|
|
59 for (String className : classNames) {
|
|
60 matchClassNames(ret, className);
|
|
61 }
|
|
62 List<Class<?>> ret0 = toClass(ret);
|
|
63 for (Class<?> c : ret0) {
|
|
64 saveTemplateClass(registry, c);
|
|
65 }
|
|
66 }
|
|
67
|
|
68 @SuppressWarnings("serial")
|
|
69 private static void matchClassNames(List<String> ret, final String className)
|
|
70 throws IOException {
|
|
71 String packageName = className.substring(0, className.lastIndexOf('.'));
|
|
72 String relativedName = className.substring(
|
|
73 className.lastIndexOf('.') + 1, className.length());
|
|
74 String patName = relativedName.replace("*", "(\\w+)");
|
|
75 Pattern pat = Pattern.compile(patName);
|
|
76
|
|
77 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
|
|
78 JavaFileManager fm = compiler.getStandardFileManager(
|
|
79 new DiagnosticCollector<JavaFileObject>(), null, null);
|
|
80 HashSet<JavaFileObject.Kind> kind = new HashSet<JavaFileObject.Kind>() {
|
|
81 {
|
|
82 add(JavaFileObject.Kind.CLASS);
|
|
83 }
|
|
84 };
|
|
85
|
|
86 for (JavaFileObject f : fm.list(StandardLocation.PLATFORM_CLASS_PATH, packageName, kind, false)) {
|
|
87 String relatived0 = f.getName();
|
|
88 String name0 = relatived0.substring(0, relatived0.length() - ".class".length());
|
|
89 Matcher m = pat.matcher(name0);
|
|
90 if (m.matches()) {
|
|
91 String name = packageName + '.' + name0;
|
|
92 if (!ret.contains(name)) {
|
|
93 ret.add(name);
|
|
94 }
|
|
95 }
|
|
96 }
|
|
97 }
|
|
98
|
|
99 private static List<Class<?>> toClass(List<String> classNames)
|
|
100 throws ClassNotFoundException {
|
|
101 List<Class<?>> ret = new ArrayList<Class<?>>(classNames.size());
|
|
102 ClassLoader cl = TemplatePrecompiler.class.getClassLoader();
|
|
103 for (String className : classNames) {
|
|
104 Class<?> c = cl.loadClass(className);
|
|
105 ret.add(c);
|
|
106 }
|
|
107 return ret;
|
|
108 }
|
|
109
|
|
110 public static void saveTemplateClasses(TemplateRegistry registry, Class<?>[] targetClasses)
|
|
111 throws IOException {
|
|
112 for (Class<?> c : targetClasses) {
|
|
113 saveTemplateClass(registry, c);
|
|
114 }
|
|
115 }
|
|
116
|
|
117 public static void saveTemplateClass(TemplateRegistry registry, Class<?> targetClass)
|
|
118 throws IOException {
|
|
119 LOG.info("Saving template of " + targetClass.getName() + "...");
|
|
120 Properties props = System.getProperties();
|
|
121 String distDirName = getDirName(props, DEST, DEFAULT_DEST);
|
|
122 if (targetClass.isEnum()) {
|
|
123 throw new UnsupportedOperationException(
|
|
124 "Not supported enum type yet: " + targetClass.getName());
|
|
125 } else {
|
|
126 new JavassistTemplateBuilder(registry).writeTemplate(targetClass,
|
|
127 distDirName);
|
|
128 }
|
|
129 LOG.info("Saved .class file of template class of " + targetClass.getName());
|
|
130 }
|
|
131
|
|
132 public static boolean deleteTemplateClass(Class<?> targetClass)
|
|
133 throws IOException {
|
|
134 LOG.info("Deleting template of " + targetClass.getName() + "...");
|
|
135 Properties props = System.getProperties();
|
|
136 String distDirName = getDirName(props, DEST, DEFAULT_DEST);
|
|
137 String targetClassName = targetClass.getName();
|
|
138 String targetClassFileName = targetClassName.replace('.',
|
|
139 File.separatorChar) + "_$$_Template.class";
|
|
140 File targetFile = new File(distDirName + File.separatorChar
|
|
141 + targetClassFileName);
|
|
142 boolean deleted = false;
|
|
143 if (!targetFile.isDirectory() && targetFile.exists()) {
|
|
144 deleted = targetFile.delete();
|
|
145 }
|
|
146 LOG.info("Deleted .class file of template class of " + targetClass.getName());
|
|
147 return deleted;
|
|
148 }
|
|
149
|
|
150 private static String getDirName(Properties props, String dirName, String defaultDirName)
|
|
151 throws IOException {
|
|
152 String dName = props.getProperty(dirName, defaultDirName);
|
|
153 File d = new File(dName);
|
|
154 if (!d.isDirectory() && !d.exists()) {
|
|
155 throw new IOException("Directory not exists: " + dName);
|
|
156 }
|
|
157 return d.getAbsolutePath();
|
|
158 }
|
|
159
|
|
160 public static void main(final String[] args) throws Exception {
|
|
161 TemplatePrecompiler.saveTemplates(args);
|
|
162 }
|
|
163 }
|