/*
* Copyright 2009-2016 Tilmann Zaeschke. All rights reserved.
*
* This file is part of ZooDB.
*
* ZooDB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ZooDB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ZooDB. If not, see <http://www.gnu.org/licenses/>.
*
* See the README and COPYING files for further information.
*/
package org.zoodb.internal.util;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import org.zoodb.api.impl.ZooPC;
public class ClassCreator extends URLClassLoader {
private static final ClassCreator SINGLETON = new ClassCreator();
private static byte[] ba = new byte[1000];
private static final byte[] BA = {
-54, -2, -70, -66, // 0-3: magic number
0, 0, //4-5: minor version
0, 50, //6-7: major version
0, 16, //8-9: constant pools size+1
7, 0, 2, 1, 0, 11, 98, 99, 101, 47,
77, 121, 67, 108, 97, 115, 115, 7, 0, 4,
1, 0, 25, 98, 99, 101, 47, 80, 101, 114,
115, 105, 115, 116, 101, 110, 116, 67, 97, 112,
97, 98, 108, 101, 73, 109, 112, 108, 1, 0,
6, 60, 105, 110, 105, 116, 62, 1, 0, 3,
40, 41, 86, 1, 0, 4, 67, 111, 100, 101,
10, 0, 3, 0, 9, 12, 0, 5, 0, 6,
1, 0, 15, 76, 105, 110, 101, 78, 117, 109,
98, 101, 114, 84, 97, 98, 108, 101, 1, 0,
18, 76, 111, 99, 97, 108, 86, 97, 114, 105,
97, 98, 108, 101, 84, 97, 98, 108, 101, 1,
0, 4, 116, 104, 105, 115, 1, 0, 13, 76,
98, 99, 101, 47, 77, 121, 67, 108, 97, 115,
115, 59, 1, 0, 10, 83, 111, 117, 114, 99,
101, 70, 105, 108, 101, 1, 0, 12, 77, 121,
67, 108, 97, 115, 115, 46, 106, 97, 118, 97,
0, 33, 0, 1, 0, 3, 0, 0, 0, 0,
0, 1, 0, 1, 0, 5, 0, 6, 0, 1,
0, 7, 0, 0, 0, 47, 0, 1, 0, 1,
0, 0, 0, 5, 42, -73, 0, 8, -79, 0,
0, 0, 2, 0, 10, 0, 0, 0, 6, 0,
1, 0, 0, 0, 3, 0, 11, 0, 0, 0,
12, 0, 1, 0, 0, 0, 5, 0, 12, 0,
13, 0, 0, 0, 1, 0, 14, 0, 0, 0,
2, 0, 15
};
private final HashMap<String, Class<?>> map =
new HashMap<String, Class<?>>();
private ClassCreator() {
super(new URL[]{}, ClassCreator.class.getClassLoader());
}
/**
* @param className Class name.
*/
public static Class<?> createClass(String className, String superClassName) {
Class<?> cls = SINGLETON.map.get(className);
if (cls != null) {
return cls;
}
// if (true) {
byte[] b = ClassBuilderSimple.build(className, superClassName);
cls = SINGLETON.defineClass(className, b, 0, b.length);
SINGLETON.map.put(className, cls);
return cls;
// }
//
//
// int len = BA.length;
// System.arraycopy(BA, 0, ba, 0, len);
//
// String name = convertDots(className);
// String superName = convertDots(superClassName);
//
// String shortName = name.substring(name.lastIndexOf('/') + 1);
// shortName += ".java";
//
// System.out.println("shortName = " + shortName);
// System.out.println(" name = " + name);
// System.out.println("superName = " + superName);
// len += replace(shortName, 166, 168, 0, 12);
// len += replace(name, 137, 140, 2, 11);
// len += replace(superName, 31, 33, 0, 25);
// len += replace(name, 14, 16, 0, 11);
//
// cls = SINGLETON.defineClass(name, ba, 0, len);
//
// SINGLETON.map.put(name, cls);
//
// return cls;
}
public static Class<?> createClass(String className) {
Class<?> cls = SINGLETON.map.get(className);
if (cls != null) {
return cls;
}
int len = BA.length;
System.arraycopy(BA, 0, ba, 0, len);
String name = convertDots(className);
String superName = convertDots(ZooPC.class.getName());
String shortName = name.substring(name.lastIndexOf('/') + 1);
shortName += ".java";
System.out.println("shortName = " + shortName);
System.out.println(" name = " + name);
System.out.println("superName = " + superName);
len += replace(shortName, 166, 168, 0, 12);
len += replace(name, 137, 140, 2, 11);
len += replace(superName, 31, 33, 0, 25);
len += replace(name, 14, 16, 0, 11);
cls = SINGLETON.defineClass(name, ba, 0, len);
SINGLETON.map.put(name, cls);
return cls;
}
private static int replace(String newName, int posLen, int posName,
int deltaLen, int lenToReplace) {
ba[posLen] = (byte) (newName.length() + deltaLen >> 8);
ba[posLen+1] = (byte) (newName.length() + deltaLen);
int toCopy = BA.length - posName - lenToReplace;
System.arraycopy(ba, posName + lenToReplace, ba, posName + newName.length(),
toCopy);
for (int i = 0; i < newName.length(); i++) {
ba[posName+i] = (byte) newName.charAt(i);
}
//return delta len
int deltaSize = newName.length() - lenToReplace;
return deltaSize;
}
private static final String convertDots(String name) {
StringBuilder sb = new StringBuilder(name.length());
for (int i = 0; i < name.length(); i++) {
char c = name.charAt(i);
if (c == '.') {
sb.append('/');
} else {
sb.append(c);
}
}
return sb.toString();
}
}