001 /* 002 Renaud Pawlak, pawlak@cnam.fr, CEDRIC Laboratory, Paris, France. 003 Lionel Seinturier, Lionel.Seinturier@lip6.fr, LIP6, Paris, France. 004 005 JAC-Core is free software. You can redistribute it and/or modify it 006 under the terms of the GNU Library General Public License as 007 published by the Free Software Foundation. 008 009 JAC-Core is distributed in the hope that it will be useful, but 010 WITHOUT ANY WARRANTY; without even the implied warranty of 011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 012 013 This work uses the Javassist system - Copyright (c) 1999-2000 014 Shigeru Chiba, University of Tsukuba, Japan. All Rights Reserved. */ 015 016 package org.objectweb.jac.core.utils; 017 018 import java.io.ByteArrayInputStream; 019 import java.io.ByteArrayOutputStream; 020 import java.io.BufferedInputStream; 021 import java.io.File; 022 import java.io.FileInputStream; 023 import java.io.InputStream; 024 import java.io.ObjectInputStream; 025 import java.io.ObjectOutputStream; 026 import java.io.OutputStream; 027 import java.lang.reflect.Field; 028 029 import java.util.Enumeration; 030 import java.util.Hashtable; 031 import java.util.StringTokenizer; 032 import java.util.Vector; 033 034 035 /** 036 * Lib is a container class for various utility method used by org.objectweb.jac. 037 * 038 * None of these methods is attached to any particular jac files but 039 * should be, in an ideal world, provided by the JDK. 040 */ 041 042 043 public class Lib { 044 045 /** 046 * Execute a command in a process and dump its standard output and error. 047 * 048 * @param command the command to execute 049 */ 050 051 public static void exec(String command) { 052 053 Runtime runtime = Runtime.getRuntime(); 054 055 try { 056 057 Process p = runtime.exec(command); 058 059 byte[] buf = new byte[1024]; 060 int len; 061 062 063 /** Dump the output stream of the process */ 064 065 InputStream in = new BufferedInputStream( p.getInputStream() ); 066 for ( len=in.read(buf) ; len != -1 ; len=in.read(buf) ) 067 System.out.write( buf, 0, len ); 068 069 070 /** Dump the error stream of the process */ 071 072 in = new BufferedInputStream( p.getErrorStream() ); 073 for ( len=in.read(buf) ; len != -1 ; len=in.read(buf) ) 074 System.err.write( buf, 0, len ); 075 076 077 /** Wait for the end of the process */ 078 079 p.waitFor(); 080 081 } 082 catch ( Exception e ) { 083 e.printStackTrace(); 084 System.exit(1); 085 } 086 } 087 088 089 /** 090 * Transform strings stored as a enumeration object into 091 * a space-separated string. 092 * 093 * @param stringsEnum the enumeration object containing the strings 094 * @return a space-separated string composed of 095 * the string contained in <I>stringsEnum</I> 096 */ 097 098 public static String stringsEnumToString(Enumeration stringsEnum) { 099 100 String str = ""; 101 102 while ( stringsEnum.hasMoreElements() ) { 103 str += (String) stringsEnum.nextElement() + " "; 104 } 105 106 return str; 107 } 108 109 110 /** 111 * Transform strings stored as a enumeration object into 112 * an array of strings. 113 * 114 * @param stringsEnum the enumeration object containing the strings 115 * @return an array of strings composed of 116 * the string contained in <I>stringsEnum</I> 117 */ 118 119 public static String[] stringsEnumToStringArray(Enumeration stringsEnum) { 120 121 String str = stringsEnumToString(stringsEnum); 122 StringTokenizer strTok = new StringTokenizer(str); 123 int len = strTok.countTokens(); 124 125 String[] strArray = new String[len]; 126 127 for (int i=0; i<len ; i++) { 128 strArray[i] = new String(strTok.nextToken()); 129 } 130 131 return strArray; 132 } 133 134 135 /** 136 * Transform object stored as a enumeration object into 137 * an array of object. 138 * 139 * @param enum the enumeration object containing the objects 140 * @return an array of objects composed of 141 * the objects contained in <I>enum</I> 142 */ 143 144 public static Object[] enumToArray(Enumeration enum) { 145 146 Vector elements = new Vector(); 147 148 while ( enum.hasMoreElements() ) 149 elements.add( enum.nextElement() ); 150 151 return elements.toArray(); 152 } 153 154 155 /** 156 * Transform a string composed of substrings separated by spaces into 157 * an array composed of the substrings. 158 * 159 * @param str the string composed of substrings separated by spaces 160 * @return an array composed of the substrings 161 */ 162 163 public static String[] stringToStringArray(String str) { 164 165 StringTokenizer strTok = new StringTokenizer(str); 166 int len = strTok.countTokens(); 167 168 String[] strArray = new String[len]; 169 170 for (int i=0; i<len ; i++) { 171 strArray[i] = new String(strTok.nextToken()); 172 } 173 174 return strArray; 175 } 176 177 178 /** 179 * Store a string array into a hashtable. 180 * 181 * @param strs the string array 182 * @return the hashtable 183 */ 184 185 public static Hashtable stringArrayToHashtable(String[] strs) { 186 187 Hashtable ret = new Hashtable(); 188 189 for (int i=0; i<strs.length; i++) { 190 ret.put(strs[i], ""); 191 } 192 193 return ret; 194 } 195 196 197 /** 198 * Return the byte code contained in file 199 * <I>dirName</I>.<I>fileName</I>.class 200 * 201 * @param dirName the directory where the file is stored 202 * @param fileName the file name 203 * @return the byte code 204 */ 205 206 public static byte[] loadByteCodeFromFile(String dirName, String fileName) 207 { 208 209 byte[] byteCode = null; 210 211 try { 212 213 String fullFileName = 214 dirName + new String(fileName).replace('.','/') + ".class"; 215 216 File file = new File( fullFileName ); 217 long fileSize = file.length(); 218 if ( fileSize == 0 ) return null; 219 220 byteCode = new byte[ (int) fileSize ]; 221 InputStream in = new BufferedInputStream( new FileInputStream(file) ); 222 if ( in.read(byteCode) != fileSize ) return null; 223 224 } 225 catch( Exception e ) { e.printStackTrace(); } 226 227 return byteCode; 228 } 229 230 231 /** 232 * Serialize an object into an array of bytes. 233 * 234 * @param src the object to serialize 235 * @return an array of bytes 236 */ 237 238 public static byte[] serialize(Object src) { 239 240 return serialize(src, ObjectOutputStream.class); 241 } 242 243 244 /** 245 * Serialize an object into an array of bytes. 246 * 247 * @param src the object to serialize 248 * @param oosClass the subclass of ObjectOutputStream 249 * to use for serializing src 250 * @return an array of bytes 251 */ 252 253 public static byte[] serialize(Object src, Class oosClass) { 254 255 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 256 257 ObjectOutputStream oos = null; 258 byte[] ret = null; 259 260 try { 261 262 oos = 263 (ObjectOutputStream) 264 oosClass. 265 getConstructor( new Class[]{OutputStream.class} ). 266 newInstance( new Object[]{baos} ); 267 268 oos.writeObject( src ); 269 oos.close(); 270 271 ret = baos.toByteArray(); 272 baos.close(); 273 274 } 275 catch( Exception e ) { e.printStackTrace(); } 276 277 return ret; 278 } 279 280 281 /** 282 * Deserialize an object from an array of bytes. 283 * 284 * @param buf the array of bytes 285 * @return the object or null if a error has been encountered 286 */ 287 288 public static Object deserialize(byte[] buf) { 289 290 return deserialize( buf, ObjectInputStream.class ); 291 } 292 293 294 /** 295 * Deserialize an object from an array of bytes. 296 * 297 * @param data the array of bytes 298 * @param oisClass the subclass of ObjectInputStream 299 * to use for deserializing src 300 * @return the object or null if a error has been encountered 301 */ 302 303 public static Object deserialize( byte[] data, Class oisClass ) { 304 305 ByteArrayInputStream bais = new ByteArrayInputStream(data); 306 307 ObjectInputStream ois = null; 308 Object ret = null; 309 310 try { 311 312 ois = 313 (ObjectInputStream) 314 oisClass. 315 getConstructor( new Class[]{InputStream.class} ). 316 newInstance( new Object[]{bais} ); 317 318 ret = ois.readObject(); 319 ois.close(); 320 bais.close(); 321 322 } 323 catch( Exception e ) { e.printStackTrace(); } 324 325 return ret; 326 } 327 328 329 /** 330 * Get fields name. 331 * 332 * @param src the source object containing the fields 333 * @return the fields name as an array of strings 334 */ 335 336 public static String[] getFieldsName( Object src ) { 337 338 String[] fieldsName = null; 339 340 try { 341 342 Field[] fields = src.getClass().getFields(); 343 fieldsName = new String[ fields.length ]; 344 345 for ( int i=0 ; i < fields.length ; i++ ) { 346 fieldsName[i] = fields[i].getName(); 347 } 348 349 } 350 catch( Exception e ) { e.printStackTrace(); } 351 352 return fieldsName; 353 } 354 355 356 /** 357 * Get fields value. 358 * 359 * @param src the source object containing the fields 360 * @return the fields value as an array of objects 361 */ 362 363 public static Object[] getFieldsValue( Object src ) { 364 365 Object[] fieldsValue = null; 366 367 try { 368 369 Field[] fields = src.getClass().getFields(); 370 fieldsValue = new Object[ fields.length ]; 371 372 for ( int i=0 ; i < fields.length ; i++ ) { 373 fieldsValue[i] = fields[i].get( src ); 374 } 375 376 } 377 catch( Exception e ) { e.printStackTrace(); } 378 379 return fieldsValue; 380 } 381 382 383 /** 384 * Get fields value. 385 * 386 * @param src the source object containing the fields 387 * @param fieldsName the fields name 388 * @return the fields value as an array of objects 389 */ 390 391 public static Object[] getFieldsValue( Object src, String[] fieldsName ) { 392 393 Object[] fieldsValue = null; 394 395 try { 396 397 Class cl = src.getClass(); 398 fieldsValue = new Object[ fieldsName.length ]; 399 400 for ( int i=0 ; i < fieldsName.length ; i++ ) { 401 fieldsValue[i] = cl.getField(fieldsName[i]).get( src ); 402 } 403 404 } 405 catch( Exception e ) { e.printStackTrace(); } 406 407 return fieldsValue; 408 } 409 410 411 /** 412 * Set fields value. 413 * 414 * @param src the source object 415 * @param fieldsName the fields name 416 * @param fieldsValue the fields value 417 */ 418 419 public static void setFieldsValue(Object src, String[] fieldsName, Object[] fieldsValue) { 420 try { 421 Class cl = src.getClass(); 422 for (int i=0; i<fieldsName.length; i++) { 423 cl.getField(fieldsName[i]).set(src, fieldsValue[i]); 424 } 425 } catch (Exception e) { 426 e.printStackTrace(); 427 } 428 } 429 430 /** 431 * Get classes. 432 * 433 * @param objs the objects as an array 434 * @return the array of classes where each element is the class 435 * of the corresponding object 436 */ 437 438 public static Class[] getClasses( Object[] objs ) { 439 440 Class cl; 441 Field fieldTYPE; 442 Class[] cls = new Class[ objs.length ]; 443 444 for ( int i=0 ; i < objs.length ; i++ ) { 445 446 if( objs[i] != null ) { 447 cl = objs[i].getClass(); 448 449 /** 450 * Check whether the class is a wrapper for a primitive type. 451 * Heuristic used: search for a field called TYPE. 452 */ 453 454 try { 455 fieldTYPE = cl.getField("TYPE"); 456 cls[i] = (Class) fieldTYPE.get( objs[i] ); 457 } 458 catch( NoSuchFieldException e ) { cls[i] = cl; } 459 catch( IllegalAccessException e ) { cls[i] = cl; } 460 } else { 461 cls[i] = Object.class; 462 } 463 } 464 return cls; 465 } 466 467 468 /** 469 * Recursively pretty prints an array. 470 * 471 * @param o the array 472 */ 473 474 public static void printArray( Object o ) { 475 476 if ( o == null ) { 477 System.out.print ( " <null> " ); 478 return; 479 } 480 481 if ( o.getClass().isArray() ) { 482 483 System.out.print ( "[ " ); 484 485 for ( int i = 0; i < ((Object[])o).length; i++ ) { 486 printArray( ((Object[])o)[i] ); 487 } 488 489 System.out.print ( "]" ); 490 491 } else { 492 System.out.print ( o + " " ); 493 } 494 495 } 496 497 }