1 19 20 package org.netbeans.nbbuild; 21 22 import java.io.File ; 23 import java.io.FileInputStream ; 24 import java.io.FileOutputStream ; 25 import java.io.IOException ; 26 import java.lang.reflect.Method ; 27 import java.util.ArrayList ; 28 import java.util.HashMap ; 29 import java.util.List ; 30 import java.util.Map ; 31 import org.apache.tools.ant.*; 32 import org.apache.tools.ant.types.*; 33 34 37 public class NbEnhanceClass extends Task { 38 39 40 private Path patchPath; 41 public Path createClasspath() { 42 if (patchPath == null) { 43 patchPath = new Path(getProject()); 44 } 45 return patchPath.createPath(); 46 } 47 48 49 private String patchClass = "org.netbeans.PatchByteCode"; 50 public void setPatchClass (String f) { 51 patchClass = f; 52 } 53 54 56 private String enhanceMethod = "enhanceClass"; 57 public void setEnhanceMethod (String f) { 58 enhanceMethod = f; 59 } 60 61 62 private File basedir; 63 public void setBasedir (File f) { 64 basedir = f; 65 } 66 67 69 public static class Patch { 70 String clazz; 71 String nbSuperClass; 72 String nbImplements; 73 List <Member> members; 74 75 76 77 public void setClass (String s) { 78 clazz = s; 79 } 80 81 public void setSuper (String s) { 82 nbSuperClass = s; 83 } 84 public void setImplements (String s) { 85 nbImplements = s; 86 } 87 88 public Object createMember () { 89 Member m = new Member(); 90 if (members == null) { 91 members = new ArrayList <Member>(); 92 } 93 members.add (m); 94 return m; 95 } 96 97 public static final class Member extends Object { 98 String name; 99 String rename; 100 101 public void setName (String s) { 102 name = s; 103 } 104 105 public void setRename (String s) { 106 rename = s; 107 } 108 } 109 } 110 private List <Patch> patches = new ArrayList <Patch>(); 111 public Patch createPatch () { 112 Patch n = new Patch (); 113 patches.add(n); 114 return n; 115 } 116 117 118 public void execute() throws BuildException { 119 if (basedir == null) { 120 throw new BuildException ("Attribute basedir must be specified"); 121 } 122 123 if (patches.isEmpty()) { 124 return; 126 } 127 128 132 ClassLoader cl = new AntClassLoader(getProject(), patchPath, false); 133 134 Method m; 135 try { 136 Class <?> c = cl.loadClass(patchClass); 137 m = c.getMethod(enhanceMethod, byte[].class, Map .class); 138 if (m.getReturnType() != byte[].class) { 139 throw new BuildException ("Method does not return byte[]: " + m); 140 } 141 } catch (Exception ex) { 142 throw new BuildException ("Cannot initialize class " + patchClass + " and method " + enhanceMethod, ex); 143 } 144 145 153 154 158 for (Patch p : patches) { 159 if (p.clazz == null) { 160 throw new BuildException ("Attribute class must be specified"); 161 } 162 163 File f = new File (basedir, p.clazz + ".class"); 164 if (!f.exists ()) { 165 throw new BuildException ("File " + f + " for class " + p.clazz + " does not exists"); 166 } 167 168 byte[] arr = new byte[(int)f.length()]; 169 try { 170 FileInputStream is = new FileInputStream (f); 171 if (arr.length != is.read (arr)) { 172 throw new BuildException ("Not all bytes read"); 173 } 174 is.close (); 175 } catch (IOException ex) { 176 throw new BuildException ("Cannot read file " + f, ex); 177 } 178 179 List <String > members = null; 180 List <String > rename = null; 181 if (p.members != null) { 182 members = new ArrayList <String >(); 183 for (Patch.Member mem : p.members) { 184 members.add (mem.name); 185 186 if (mem.rename != null) { 187 if (rename == null) { 188 rename = new ArrayList <String >(); 189 } 190 rename.add (mem.name); 191 rename.add (mem.rename); 192 } 193 } 194 } 195 196 197 byte[] out; 198 try { 199 Map <String ,Object > args = new HashMap <String ,Object >(); 200 if (p.nbSuperClass != null) { 201 args.put ("netbeans.superclass", p.nbSuperClass); 202 } 203 if (p.nbImplements != null) { 204 args.put ("netbeans.interfaces", p.nbImplements); 205 } 206 if (members != null) { 207 args.put ("netbeans.public", members); 208 } 209 if (rename != null) { 210 args.put ("netbeans.rename", rename); 211 } 212 213 log("Patching " + p.clazz + " with arguments " + args, Project.MSG_VERBOSE); 214 215 out = (byte[]) m.invoke(null, arr, args); 216 if (out == null) { 217 continue; 219 } 220 } catch (Exception ex) { 221 throw new BuildException (ex); 222 } 223 224 if (p.nbSuperClass != null) { 225 log ("Enhanced " + f + " to have alternate superclass " + p.nbSuperClass + " and be public"); 226 } else { 227 log ("Enhanced " + f + " to be public"); 228 } 229 230 try { 231 FileOutputStream os = new FileOutputStream (f); 232 os.write (out); 233 os.close (); 234 } catch (IOException ex) { 235 throw new BuildException ("Cannot overwrite file " + f, ex); 236 } 237 } 238 } 239 240 } 241 | Popular Tags |