1 28 29 30 package org.jibx.binding; 31 32 import java.io.ByteArrayOutputStream ; 33 import java.io.File ; 34 import java.io.IOException ; 35 import java.net.URL ; 36 import java.net.URLClassLoader ; 37 38 import org.apache.bcel.classfile.Method; 39 import org.apache.bcel.verifier.VerificationResult; 40 import org.apache.bcel.verifier.Verifier; 41 import org.apache.bcel.verifier.VerifierFactory; 42 import org.jibx.binding.classes.BoundClass; 43 import org.jibx.binding.classes.BranchWrapper; 44 import org.jibx.binding.classes.ClassCache; 45 import org.jibx.binding.classes.ClassFile; 46 import org.jibx.binding.classes.MungedClass; 47 import org.jibx.binding.def.BindingDefinition; 48 import org.jibx.runtime.JiBXException; 49 50 57 58 public class Compile 59 { 60 private boolean m_verbose; 61 private boolean m_load; 62 private boolean m_verify; 63 private boolean m_trackBranches; 64 private boolean m_errorOverride; 65 private boolean m_skipValidate; 66 67 70 71 public Compile() {} 72 73 82 public Compile(boolean verbose, boolean load, boolean verify, 83 boolean track, boolean over) { 84 m_verbose = verbose; 85 m_load = load; 86 m_verify = verify; 87 m_trackBranches = track; 88 m_errorOverride = over; 89 } 90 91 100 private boolean verifyBCEL(ClassFile file) { 101 try { 102 103 Verifier verifier = VerifierFactory.getVerifier(file.getName()); 105 106 boolean verified = false; 108 VerificationResult vr = verifier.doPass1(); 109 if (vr.getStatus() == VerificationResult.VERIFIED_OK) { 110 vr = verifier.doPass2(); 111 if (vr.getStatus() == VerificationResult.VERIFIED_OK) { 112 Method[] methods = file.getRawClass().getMethods(); 113 for (int j = 0; j < methods.length; j++) { 114 vr = verifier.doPass3a(j); 115 if (vr.getStatus() == VerificationResult.VERIFIED_OK) { 116 vr = verifier.doPass3b(j); 117 } 118 if (vr.getStatus() == VerificationResult.VERIFIED_OK) { 119 verified = true; 120 } else { 121 System.out.println 122 ("Verification failure on method " + 123 methods[j].getName() + " of class " + 124 file.getName() + ":"); 125 System.out.println(" " + vr.toString()); 126 } 127 } 128 } else { 129 System.out.println("Verification failure on class " + 130 file.getName() + ":"); 131 System.out.println(" " + vr.toString()); 132 } 133 } else { 134 System.out.println("Verification failure on class " + 135 file.getName() + ":"); 136 System.out.println(" " + vr.toString()); 137 } 138 return verified; 139 140 } catch (Exception ex) { System.out.println("BCEL failure:"); 142 ex.printStackTrace(); 143 return false; 144 } 145 } 146 147 155 private void handleOutput(String [] paths) 156 throws JiBXException, IOException { 157 158 ClassFile[][] lists = MungedClass.fixChanges(true); 160 161 ClassFile[] files = lists[0]; 163 if (m_verbose) { 164 System.out.println("\nWrote " + files.length + " files"); 165 } 166 if (m_verbose || m_load) { 167 168 URL [] urls = null; 170 if (m_load) { 171 urls = new URL [paths.length]; 172 for (int i = 0; i < urls.length; i++) { 173 urls[i] = new File (paths[i]).toURL(); 174 } 175 } 176 for (int i = 0; i < files.length; i++) { 177 178 ClassFile file = files[i]; 180 ByteArrayOutputStream bos = new ByteArrayOutputStream (); 181 file.writeFile(bos); 182 byte[] bytes = bos.toByteArray(); 183 if(m_verbose){ 184 System.out.println("\n " + file.getName() + 185 " output file size is " + bytes.length + " bytes"); 186 } 187 188 if (m_verify) { 190 verifyBCEL(file); 191 } 192 193 if (m_load) { 195 DirectLoader cloader = new DirectLoader(urls); 196 Class clas = cloader.load(file.getName(), bytes); 197 if (m_verbose) { 198 java.lang.reflect.Method [] methods = 199 clas.getDeclaredMethods(); 200 System.out.println(" Found " + methods.length + 201 " methods:"); 202 for (int j = 0; j < methods.length; j++) { 203 java.lang.reflect.Method method = methods[j]; 204 System.out.println(" " + 205 method.getReturnType().getName() + " " + 206 method.getName()); 207 } 208 } 209 } 210 } 211 } 212 213 if (m_verbose) { 215 files = lists[1]; 216 System.out.println("\nKept " + files.length + " files unchanged:"); 217 for (int i = 0; i < files.length; i++) { 218 System.out.println(" " + files[i].getName()); 219 } 220 files = lists[2]; 221 System.out.println("\nDeleted " + files.length + " files:"); 222 for (int i = 0; i < files.length; i++) { 223 System.out.println(" " + files[i].getName()); 224 } 225 } 226 } 227 228 233 public void setLoad(boolean load) { 234 m_load = load; 235 } 236 237 242 public void setVerbose(boolean verbose) { 243 m_verbose = verbose; 244 } 245 246 251 public void setVerify(boolean verify) { 252 m_verify = verify; 253 } 254 255 260 public void setSkipValidate(boolean skip) { 261 m_skipValidate = skip; 262 } 263 264 271 public void compile(String [] paths, String [] files) throws JiBXException { 272 try { 273 274 if (m_verbose) { 276 System.out.println("Running binding compiler version " + 277 BindingDefinition.CURRENT_VERSION_NAME); 278 } 279 280 ClassCache.setPaths(paths); 282 ClassFile.setPaths(paths); 283 284 BoundClass.reset(); 286 MungedClass.reset(); 287 BindingDefinition.reset(); 288 BranchWrapper.setTracking(m_trackBranches); 289 BranchWrapper.setErrorOverride(m_errorOverride); 290 291 BindingDefinition[] defs = new BindingDefinition[files.length]; 293 for (int i = 0; i < files.length; i++) { 294 defs[i] = Utility.loadFileBinding(files[i], !m_skipValidate); 295 if (m_verbose) { 296 defs[i].print(); 297 } 298 } 299 300 for (int i = 0; i < defs.length; i++) { 302 try { 303 defs[i].generateCode(m_verbose); 304 } catch (RuntimeException e) { 305 throw new JiBXException 306 ("\n*** Error during code generation - please report " + 307 "this error on the JiBX users list so that the " + 308 "condition can be caught during validation ***\n", e); 309 } 310 } 311 312 handleOutput(paths); 314 315 } catch (IOException ex) { 316 throw new JiBXException("IOException in compile", ex); 317 } catch (ExceptionInInitializerError ex) { 318 throw new JiBXException("Error during initialization;" + 319 " is jibx-run.jar in load classpath?", ex.getException()); 320 } catch (Throwable ex) { 321 throw new JiBXException("Error running binding compiler", ex); 322 } 323 } 324 325 330 public static void main(String [] args) { 331 if (args.length > 0) { 332 try { 333 334 boolean verbose = false; 336 boolean load = false; 337 boolean verify = false; 338 boolean track = false; 339 boolean over = false; 340 boolean skip = false; 341 int offset = 0; 342 for (; offset < 5 && offset < args.length; offset++) { 343 String arg = args[offset]; 344 if ("-v".equalsIgnoreCase(arg)) { 345 verbose = true; 346 } else if ("-l".equalsIgnoreCase(arg)) { 347 load = true; 348 } else if ("-b".equalsIgnoreCase(arg)) { 349 verify = true; 350 } else if ("-o".equalsIgnoreCase(arg)) { 351 over = true; 352 } else if ("-s".equalsIgnoreCase(arg)) { 353 skip = true; 354 } else if ("-t".equalsIgnoreCase(arg)) { 355 track = true; 356 } else { 357 break; 358 } 359 } 360 361 String [] clsspths = Utility.getClassPaths(); 363 String [] bindings = new String [args.length - offset]; 364 System.arraycopy(args, offset, bindings, 0, bindings.length); 365 366 if (verbose) { 368 System.out.println("Using paths:"); 369 for (int i = 0; i < clsspths.length; i++) { 370 System.out.println(" " + clsspths[i]); 371 } 372 System.out.println("Using bindings:"); 373 for (int i = 0; i < bindings.length; i++) { 374 System.out.println(" " + bindings[i]); 375 } 376 } 377 378 Compile compiler = 380 new Compile(verbose, load, verify, track, over); 381 compiler.setSkipValidate(skip); 382 compiler.compile(clsspths, bindings); 383 384 } catch (JiBXException ex) { 385 ex.printStackTrace(System.out); 386 System.exit(1); 387 } 388 389 } else { 390 System.out.println 391 ("\nUsage: java org.jibx.binding.Compile [-b] [-l] [-v] " + 392 "binding1 binding2 ...\nwhere:\n -b turns on BCEL " + 393 "verification (debug option),\n -l turns on test loading of " + 394 "modified or generated classes for validation, and\n" + 395 " -v turns on verbose output\nThe bindingn files are " + 396 "different bindings to be compiled.\n"); 397 System.exit(1); 398 } 399 } 400 401 405 private static class DirectLoader extends URLClassLoader 406 { 407 protected DirectLoader(URL [] urls) { 408 super(urls, DirectLoader.class.getClassLoader()); 409 } 410 411 protected Class load(String name, byte[] data) { 412 return defineClass(name, data, 0, data.length); 413 } 414 } 415 } | Popular Tags |