1 23 24 27 28 package com.sun.jdo.api.persistence.enhancer; 29 30 import java.io.IOException ; 31 import java.io.InputStream ; 32 import java.io.OutputStream ; 33 import java.io.PrintWriter ; 34 import java.io.DataInputStream ; 35 import java.io.DataOutputStream ; 36 37 import java.util.Properties ; 38 39 import com.sun.jdo.api.persistence.model.Model; 40 41 import com.sun.jdo.api.persistence.enhancer.meta.JDOMetaData; 42 import com.sun.jdo.api.persistence.enhancer.meta.JDOMetaDataModelImpl; 43 import com.sun.jdo.api.persistence.enhancer.meta.JDOMetaDataPropertyImpl; 44 45 import com.sun.jdo.api.persistence.enhancer.impl.EnhancerControl; 46 import com.sun.jdo.api.persistence.enhancer.impl.Environment; 47 import com.sun.jdo.api.persistence.enhancer.impl.ClassControl; 48 49 import com.sun.jdo.api.persistence.enhancer.classfile.ClassFile; 50 51 import com.sun.jdo.api.persistence.enhancer.util.Support; 53 import com.sun.jdo.api.persistence.enhancer.util.UserException; 54 import com.sun.jdo.api.persistence.enhancer.util.ClassFileSource; 55 56 57 61 62 65 public class FilterEnhancer 67 extends Support 68 implements ByteCodeEnhancer 69 { 70 static public final String DO_SIMPLE_TIMING 71 = "ByteCodeEnhancer.doSimpleTiming"; static public final String VERBOSE_LEVEL 73 = "ByteCodeEnhancer.verboseLevel"; static public final String VERBOSE_LEVEL_QUIET 75 = "quiet"; static public final String VERBOSE_LEVEL_WARN 77 = "warn"; static public final String VERBOSE_LEVEL_VERBOSE 79 = "verbose"; static public final String VERBOSE_LEVEL_DEBUG 81 = "debug"; 83 85 private Environment env = new Environment(); 86 87 private EnhancerControl econtrol = new EnhancerControl(env); 88 89 92 98 protected void init(JDOMetaData metaData, 99 Properties settings, 100 PrintWriter out, 101 PrintWriter err) 102 throws EnhancerUserException, EnhancerFatalError 103 { 104 if (metaData == null) { 105 throw new EnhancerFatalError( 107 getI18N("enhancer.internal_error", "Illegal argument: metaData == null")); } 110 111 env.setJDOMetaData(metaData); 112 113 if (err != null) 115 { 116 env.setErrorWriter(err); 117 } 118 if (out != null) 119 { 120 env.setOutputWriter(out); 121 } 122 final String verboseLevel 123 = (settings == null ? null : settings.getProperty(VERBOSE_LEVEL)); 124 if (VERBOSE_LEVEL_QUIET.equals(verboseLevel)) { 125 env.setVerbose(false); 126 env.setQuiet(true); 127 } else if (VERBOSE_LEVEL_WARN.equals(verboseLevel)) { 128 env.setVerbose(false); 129 env.setQuiet(false); 130 } else if (VERBOSE_LEVEL_VERBOSE.equals(verboseLevel)) { 131 env.setVerbose(true); 132 env.setQuiet(false); 133 } else if (VERBOSE_LEVEL_DEBUG.equals(verboseLevel)) { 134 env.setVerbose(true); 135 env.setQuiet(false); 136 } else { 137 env.setVerbose(false); 138 env.setQuiet(false); 139 } 140 141 env.setNoOptimization(true); 143 env.messageNL("FilterEnhancer: forced settings: -noopt"); } 145 146 152 public FilterEnhancer(JDOMetaData metaData, 153 Properties settings, 154 PrintWriter out, 155 PrintWriter err) 156 throws EnhancerUserException, EnhancerFatalError 157 { 158 init(metaData, settings, out, err); 159 } 160 161 167 public FilterEnhancer(Properties metaData, 168 Properties settings, 169 PrintWriter out, 170 PrintWriter err) 171 throws EnhancerUserException, EnhancerFatalError 172 { 173 if (metaData == null) { 174 throw new EnhancerFatalError( 176 getI18N("enhancer.internal_error", "Illegal argument: metaData == null")); } 179 180 final JDOMetaData meta 181 = new JDOMetaDataPropertyImpl(metaData, out); 182 init(meta, settings, out, err); 183 } 184 185 191 public FilterEnhancer(Model metaData, 192 Properties settings, 193 PrintWriter out, 194 PrintWriter err) 195 throws EnhancerUserException, EnhancerFatalError 196 { 197 if (metaData == null) { 198 throw new EnhancerFatalError( 200 getI18N("enhancer.internal_error", "Illegal argument: metaData == null")); } 203 204 final JDOMetaData meta 205 = new JDOMetaDataModelImpl(metaData, 206 env.getOutputWriter()); 207 init(meta, settings, out, err); 208 } 209 210 211 214 public boolean enhanceClassFile(InputStream inByteCode, 215 OutputStreamWrapper outByteCode) 216 throws EnhancerUserException, EnhancerFatalError 217 { 218 env.messageNL("FilterEnhancer: enhancing classfile ..."); 220 env.reset(); 222 223 final boolean changed; 225 try { 226 changed = enhanceClassFile1(inByteCode, outByteCode); 227 } catch (UserException ex) { 228 230 env.reset(); 232 throw new EnhancerUserException( 234 getI18N("enhancer.error", ex.getMessage()), 236 ex); 237 } catch (RuntimeException ex) { 238 240 env.reset(); 242 ex.printStackTrace (); 244 throw new EnhancerFatalError( 245 getI18N("enhancer.internal_error", ex.getMessage()), 247 ex); 248 } 249 250 env.messageNL(changed 251 ? "FilterEnhancer: classfile enhanced successfully." : "FilterEnhancer: classfile not changed."); return changed; 254 } 255 256 259 private boolean enhanceClassFile1(InputStream inByteCode, 260 OutputStreamWrapper outByteCode) 261 { 262 affirm(inByteCode, "Illegal argument: inByteCode == null."); affirm(outByteCode, "Illegal argument: outByteCode == null."); 266 final ClassFileSource cfs; 268 final ClassFile cf; 269 final ClassControl cc; 270 try { 271 cfs = new ClassFileSource(null, inByteCode); 273 274 final DataInputStream dis = cfs.classFileContents(); 276 cf = new ClassFile(dis); 277 280 cc = new ClassControl(cfs, cf, env); 282 env.addClass(cc); 283 284 final String className = cc.className(); 286 cfs.setExpectedClassName(className); 287 } catch (IOException ex) { 288 throw new UserException( 290 getI18N("enhancer.io_error_while_reading_stream"), ex); 292 } catch (ClassFormatError ex) { 293 throw new UserException( 295 getI18N("enhancer.class_format_error"), ex); 297 } 298 299 econtrol.modifyClasses(); 301 if (env.errorCount() > 0) { 302 env.getErrorWriter ().flush (); 304 312 313 throw new UserException(env.getLastErrorMessage ()); 315 } 316 317 boolean changed = (cc.updated() && cc.filterRequired()); 319 try { 320 if (changed) 321 { 322 env.message("writing enhanced class " + cc.userClassName() + " to output stream"); } 325 else 326 { 327 env.message("no changes on class " + cc.userClassName()); 328 } 329 outByteCode.setClassName (cc.userClassName ()); 330 final DataOutputStream dos = new DataOutputStream (outByteCode.getStream ()); 331 cf.write(dos); 332 dos.flush(); 333 } catch (IOException ex) { 334 throw new UserException( 336 getI18N("enhancer.io_error_while_writing_stream"), ex); 338 } 339 return changed; 340 } 341 342 343 346 347 public boolean enhanceClassFile (InputStream in, 348 OutputStream out) 349 throws EnhancerUserException, 350 EnhancerFatalError 351 { 352 353 return enhanceClassFile (in, new OutputStreamWrapper (out)); 354 355 } 357 358 } | Popular Tags |