00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 package org.objectweb.proactive.core.component.gen;
00032
00033 import java.lang.reflect.InvocationTargetException;
00034 import java.lang.reflect.Method;
00035 import java.util.ArrayList;
00036
00037 import javassist.CannotCompileException;
00038 import javassist.ClassPool;
00039 import javassist.CtClass;
00040 import javassist.CtField;
00041 import javassist.CtMethod;
00042 import javassist.CtNewMethod;
00043 import javassist.NotFoundException;
00044
00045 import org.objectweb.proactive.core.ProActiveRuntimeException;
00046 import org.objectweb.proactive.core.component.representative.ItfID;
00047 import org.objectweb.proactive.core.component.type.ProActiveInterfaceType;
00048 import org.objectweb.proactive.core.util.ClassDataCache;
00049
00050
00057 public class Utils {
00058
00062 public static final char GEN_ESCAPE_CHAR = 'C';
00063 public static final String GEN_ESCAPE = "" + GEN_ESCAPE_CHAR +
00064 GEN_ESCAPE_CHAR;
00065
00069 public static final char GEN_PACKAGE_SEPARATOR_CHAR = 'P';
00070 public static final String GEN_PACKAGE_SEPARATOR = "" + GEN_ESCAPE_CHAR +
00071 GEN_PACKAGE_SEPARATOR_CHAR;
00072
00076 public static final char GEN_ITF_NAME_SEPARATOR_CHAR = 'I';
00077 public static final String GEN_ITF_NAME_SEPARATOR = "" + GEN_ESCAPE_CHAR +
00078 GEN_ITF_NAME_SEPARATOR_CHAR;
00079
00083 public static final char GEN_MIDDLE_SEPARATOR_CHAR = 'O';
00084 public static final String GEN_MIDDLE_SEPARATOR = "" + GEN_ESCAPE_CHAR +
00085 GEN_MIDDLE_SEPARATOR_CHAR;
00086
00087
00088 public static final String GENERATED_DEFAULT_PREFIX = GEN_ESCAPE_CHAR +
00089 "generated";
00090 public static final String REPRESENTATIVE_DEFAULT_SUFFIX = GEN_ESCAPE_CHAR +
00091 "representative";
00092 public static final String GATHERCAST_ITF_PROXY_DEFAULT_SUFFIX = GEN_ESCAPE_CHAR +
00093 "gathercastItfProxy";
00094 public static final String COMPOSITE_REPRESENTATIVE_SUFFIX = GEN_ESCAPE_CHAR +
00095 "composite";
00096 public static final String OUTPUT_INTERCEPTOR_SUFFIX = GEN_ESCAPE_CHAR +
00097 "outputInterceptor";
00098
00099
00100 public static final String STUB_DEFAULT_PACKAGE = null;
00101
00102 public static boolean isRepresentativeClassName(String classname) {
00103 return (classname.startsWith(GENERATED_DEFAULT_PREFIX) &&
00104 classname.endsWith(REPRESENTATIVE_DEFAULT_SUFFIX));
00105 }
00106
00107 public static boolean isMetaObjectClassName(String classname) {
00108 throw new ProActiveRuntimeException("not implemented yet");
00109 }
00110
00111 public static boolean isGathercastProxyClassName(String classname) {
00112 return (classname.startsWith(GENERATED_DEFAULT_PREFIX) &&
00113 classname.endsWith(GATHERCAST_ITF_PROXY_DEFAULT_SUFFIX));
00114 }
00115
00121 public static String getInterfaceSignatureFromRepresentativeClassName(
00122 String className) {
00123 if (!isRepresentativeClassName(className)) {
00124 return null;
00125 }
00126 String tmp = className.replaceAll("^" + GENERATED_DEFAULT_PREFIX, "");
00127 tmp = tmp.replaceAll(REPRESENTATIVE_DEFAULT_SUFFIX + "$", "");
00128 tmp = unEscapeClassesName(tmp, false).get(0).toString();
00129
00130 return tmp;
00131 }
00132
00133 public static String getInterfaceNameFromRepresentativeClassName(
00134 String className) {
00135 if (!isRepresentativeClassName(className)) {
00136 return null;
00137 }
00138 String tmp = className.replaceAll("^" + GENERATED_DEFAULT_PREFIX, "");
00139 tmp = tmp.replaceAll(REPRESENTATIVE_DEFAULT_SUFFIX + "$", "");
00140 tmp = unEscapeClassesName(tmp, true).get(1).toString();
00141
00142 return tmp;
00143 }
00144
00145 public static String getInterfaceSignatureFromGathercastProxyClassName(
00146 String className) {
00147 if (!isGathercastProxyClassName(className)) {
00148 return null;
00149 }
00150 String tmp = className.replaceAll("^" + GENERATED_DEFAULT_PREFIX, "");
00151 tmp = tmp.replaceAll(GATHERCAST_ITF_PROXY_DEFAULT_SUFFIX + "$", "");
00152 tmp = unEscapeClassesName(tmp, false).get(0).toString();
00153
00154 return tmp;
00155 }
00156
00157 public static String getMetaObjectClassName(
00158 String functionalInterfaceName, String javaInterfaceName) {
00159
00160 return (GENERATED_DEFAULT_PREFIX + escapeString(javaInterfaceName) +
00161 GEN_MIDDLE_SEPARATOR +
00162 escapeString(functionalInterfaceName)
00163 );
00164 }
00165
00166 public static String getMetaObjectComponentRepresentativeClassName(
00167 String functionalInterfaceName, String javaInterfaceName) {
00168
00169 return (getMetaObjectClassName(functionalInterfaceName,
00170 javaInterfaceName) + REPRESENTATIVE_DEFAULT_SUFFIX);
00171 }
00172
00173 public static String getGatherProxyItfClassName(
00174 ProActiveInterfaceType gatherItfType) {
00175 return (getMetaObjectClassName(gatherItfType.getFcItfName(),
00176 gatherItfType.getFcItfSignature()) +
00177 GATHERCAST_ITF_PROXY_DEFAULT_SUFFIX);
00178 }
00179
00180 public static String getOutputInterceptorClassName(
00181 String functionalInterfaceName, String javaInterfaceName) {
00182
00183 return (getMetaObjectClassName(functionalInterfaceName,
00184 javaInterfaceName) + OUTPUT_INTERCEPTOR_SUFFIX);
00185 }
00186
00187 public static Class defineClass(final String className, final byte[] bytes)
00188 throws ClassNotFoundException, SecurityException, NoSuchMethodException,
00189 IllegalArgumentException, IllegalAccessException,
00190 InvocationTargetException {
00191
00192 Class clc = Class.forName("java.lang.ClassLoader");
00193 Class[] argumentTypes = new Class[4];
00194 argumentTypes[0] = className.getClass();
00195 argumentTypes[1] = bytes.getClass();
00196 argumentTypes[2] = Integer.TYPE;
00197 argumentTypes[3] = Integer.TYPE;
00198
00199 Method method = clc.getDeclaredMethod("defineClass", argumentTypes);
00200 method.setAccessible(true);
00201
00202 Object[] effectiveArguments = new Object[4];
00203 effectiveArguments[0] = className;
00204 effectiveArguments[1] = bytes;
00205 effectiveArguments[2] = new Integer(0);
00206 effectiveArguments[3] = new Integer(bytes.length);
00207
00208 return (Class) method.invoke(Thread.currentThread()
00209 .getContextClassLoader(),
00210 effectiveArguments);
00211 }
00212
00213 public static void createItfStubObjectMethods(CtClass generatedClass)
00214 throws CannotCompileException, NotFoundException {
00215
00216 CtField senderItfIDField = new CtField(ClassPool.getDefault()
00217 .get(ItfID.class.getName()),
00218 "senderItfID", generatedClass);
00219 CtField.Initializer initializer = CtField.Initializer.byExpr("null");
00220 generatedClass.addField(senderItfIDField, initializer);
00221 CtMethod senderItfIDGetter = CtNewMethod.getter("getSenderItfID",
00222 senderItfIDField);
00223 generatedClass.addMethod(senderItfIDGetter);
00224 CtMethod senderItfIDSetter = CtNewMethod.setter("setSenderItfID",
00225 senderItfIDField);
00226 generatedClass.addMethod(senderItfIDSetter);
00227 }
00228
00232 public static byte[] getClassData(String classname) {
00233 byte[] bytecode = (byte[]) ClassDataCache.instance()
00234 .getClassData(classname);
00235 if (bytecode != null) {
00236 return bytecode;
00237 }
00238 if (Utils.isRepresentativeClassName(classname)) {
00239
00240
00241 bytecode = RepresentativeInterfaceClassGenerator.generateInterfaceByteCode(classname,
00242 null);
00243
00244 if (bytecode != null) {
00245 return bytecode;
00246 }
00247 }
00248
00249 if (Utils.isGathercastProxyClassName(classname)) {
00250
00251
00252 bytecode = GatherInterfaceGenerator.generateInterfaceByteCode(classname);
00253
00254 if (bytecode != null) {
00255 return bytecode;
00256 }
00257 }
00258
00259 return null;
00260 }
00261
00267 private static String escapeString(String str) {
00268 StringBuilder sb = new StringBuilder(str.length() * 2);
00269 for (int i = 0; i < str.length(); i++) {
00270 switch (str.charAt(i)) {
00271 case GEN_ESCAPE_CHAR:
00272 sb.append(GEN_ESCAPE);
00273 break;
00274 case '.':
00275 sb.append(GEN_PACKAGE_SEPARATOR);
00276 break;
00277 case '-':
00278 sb.append(GEN_ITF_NAME_SEPARATOR);
00279 break;
00280 default:
00281 sb.append(str.charAt(i));
00282 break;
00283 }
00284 }
00285 return sb.toString();
00286 }
00287
00294 private static ArrayList<CharSequence> unEscapeClassesName(
00295 String generatedClassName, boolean withItfName)
00296 throws IllegalArgumentException {
00297 ArrayList<CharSequence> result = new ArrayList<CharSequence>();
00298 StringBuilder sb = new StringBuilder(generatedClassName.length());
00299 boolean middleFlag = false;
00300
00301
00302 int begin;
00303 if ((begin = generatedClassName.lastIndexOf('.')) == -1) {
00304 begin = 0;
00305 }
00306 for (int i = begin; i < generatedClassName.length(); i++) {
00307 char c = generatedClassName.charAt(i);
00308 if (c != GEN_ESCAPE_CHAR) {
00309 sb.append(c);
00310 } else {
00311 i++;
00312 switch (generatedClassName.charAt(i)) {
00313
00314 case GEN_ESCAPE_CHAR:
00315 sb.append(GEN_ESCAPE_CHAR);
00316 ;
00317 break;
00318 case GEN_PACKAGE_SEPARATOR_CHAR:
00319 sb.append('.');
00320 break;
00321 case GEN_ITF_NAME_SEPARATOR_CHAR:
00322 if (!middleFlag) {
00323 throw new IllegalArgumentException(
00324 "The generatedClassName is not a well formed escaped string at index " +
00325 i + ", the flag GEN_ITF_NAME_SEPARATOR (" +
00326 GEN_ITF_NAME_SEPARATOR +
00327 ") is present whereasthis is not the interface name part : " +
00328 generatedClassName);
00329 }
00330 sb.append('-');
00331 break;
00332 case GEN_MIDDLE_SEPARATOR_CHAR:
00333 result.add(sb);
00334 middleFlag = true;
00335 if (!withItfName) {
00336 return result;
00337 }
00338 sb = new StringBuilder(generatedClassName.length());
00339 break;
00340 default:
00341
00342 throw new IllegalArgumentException(
00343 "The generatedClassName is not a well formed escaped string at index " +
00344 i + " : " + generatedClassName);
00345 }
00346 }
00347 }
00348 result.add(sb);
00349 return result;
00350
00351
00352
00353
00354 }
00355 }