1 19 20 package org.netbeans.modules.debugger.jpda.ant; 21 22 import java.io.File ; 23 import java.io.FileNotFoundException ; 24 import java.io.IOException ; 25 import java.io.InputStream ; 26 import java.util.ArrayList ; 27 import java.util.HashMap ; 28 import java.util.Iterator ; 29 import java.util.List ; 30 import java.util.Map ; 31 import java.util.logging.Level ; 32 import java.util.logging.Logger ; 33 34 import org.apache.tools.ant.BuildException; 35 import org.apache.tools.ant.DirectoryScanner; 36 import org.apache.tools.ant.Project; 37 import org.apache.tools.ant.Task; 38 import org.apache.tools.ant.types.FileSet; 39 import org.apache.tools.ant.util.FileUtils; 40 41 import org.openide.filesystems.FileObject; 42 import org.openide.filesystems.FileStateInvalidException; 43 import org.openide.filesystems.FileUtil; 44 45 import org.netbeans.api.debugger.DebuggerEngine; 46 import org.netbeans.api.debugger.DebuggerManager; 47 import org.netbeans.api.debugger.jpda.JPDADebugger; 48 import org.netbeans.api.java.classpath.ClassPath; 49 import org.netbeans.api.java.queries.SourceForBinaryQuery; 50 import org.netbeans.spi.java.classpath.support.ClassPathSupport; 51 import org.netbeans.spi.debugger.jpda.EditorContext; 52 53 54 59 public class JPDAReload extends Task { 60 61 private static final Logger logger = Logger.getLogger("org.netbeans.modules.debugger.jpda.ant"); 63 private List filesets = new ArrayList (); 64 65 69 public void addFileset (FileSet fileset) { 70 filesets.add (fileset); 71 } 72 73 public void execute() throws BuildException { 74 if (logger.isLoggable(Level.FINE)) { 75 logger.fine("JPDAReload.execute(), filesets = "+filesets); 76 } 77 if (filesets.size() == 0) { 78 throw new BuildException ("A nested fileset with class to refresh in VM must be specified."); 79 } 80 81 DebuggerEngine debuggerEngine = DebuggerManager.getDebuggerManager (). 83 getCurrentEngine (); 84 if (debuggerEngine == null) { 85 throw new BuildException ("No debugging sessions was found."); 86 } 87 JPDADebugger debugger = (JPDADebugger) debuggerEngine.lookupFirst 88 (null, JPDADebugger.class); 89 if (debugger == null) { 90 throw new BuildException("Current debugger is not JPDA one."); 91 } 92 if (!debugger.canFixClasses ()) { 93 throw new BuildException("The debugger does not support Fix action."); 94 } 95 if (debugger.getState () == JPDADebugger.STATE_DISCONNECTED) { 96 throw new BuildException ("The debugger is not running"); 97 } 98 99 System.out.println ("Classes to be reloaded:"); 100 101 FileUtils fileUtils = FileUtils.newFileUtils (); 102 Map map = new HashMap (); 103 EditorContext editorContext = (EditorContext) DebuggerManager. 104 getDebuggerManager ().lookupFirst (null, EditorContext.class); 105 106 Iterator it = filesets.iterator (); 107 while (it.hasNext ()) { 108 FileSet fs = (FileSet) it.next (); 109 DirectoryScanner ds = fs.getDirectoryScanner (getProject ()); 110 String fileNames[] = ds.getIncludedFiles (); 111 File baseDir = fs.getDir (getProject ()); 112 int i, k = fileNames.length; 113 for (i = 0; i < k; i++) { 114 File f = fileUtils.resolveFile (baseDir, fileNames [i]); 115 if (f != null) { 116 FileObject fo = FileUtil.toFileObject(f); 117 if (fo != null) { 118 try { 119 String url = classToSourceURL (fo); 120 if (url != null) 121 editorContext.updateTimeStamp (debugger, url); 122 InputStream is = fo.getInputStream (); 123 long fileSize = fo.getSize (); 124 byte[] bytecode = new byte [(int) fileSize]; 125 is.read (bytecode); 126 String className = fileNames [i].substring ( 128 0, 129 fileNames [i].length () - 6 130 ).replace (File.separatorChar, '.'); 131 map.put ( 132 className, 133 bytecode 134 ); 135 System.out.println (" " + className); 136 } catch (IOException ex) { 137 ex.printStackTrace (); 138 } 139 } 140 } 141 } 142 } 143 if (logger.isLoggable(Level.FINE)) { 144 logger.fine("Reloaded classes: "+map.keySet()); 145 } 146 if (map.size () == 0) { 147 System.out.println (" No class to reload"); 148 return; 149 } 150 String error = null; 151 try { 152 debugger.fixClasses (map); 153 } catch (UnsupportedOperationException uoex) { 154 error = "The virtual machine does not support this operation: "+uoex.getLocalizedMessage(); 155 } catch (NoClassDefFoundError ncdfex) { 156 error = "The bytes don't correspond to the class type (the names don't match): "+ncdfex.getLocalizedMessage(); 157 } catch (VerifyError ver) { 158 error = "A \"verifier\" detects that a class, though well formed, contains an internal inconsistency or security problem: "+ver.getLocalizedMessage(); 159 } catch (UnsupportedClassVersionError ucver) { 160 error = "The major and minor version numbers in bytes are not supported by the VM. "+ucver.getLocalizedMessage(); 161 } catch (ClassFormatError cfer) { 162 error = "The bytes do not represent a valid class. "+cfer.getLocalizedMessage(); 163 } catch (ClassCircularityError ccer) { 164 error = "A circularity has been detected while initializing a class: "+ccer.getLocalizedMessage(); 165 } 166 if (error != null) { 167 getProject().log(error, Project.MSG_ERR); 168 throw new BuildException(error); 169 } 170 } 171 172 private String classToSourceURL (FileObject fo) { 173 try { 174 ClassPath cp = ClassPath.getClassPath (fo, ClassPath.EXECUTE); 175 FileObject root = cp.findOwnerRoot (fo); 176 String resourceName = cp.getResourceName (fo, '/', false); 177 int i = resourceName.indexOf ('$'); 178 if (i > 0) 179 resourceName = resourceName.substring (0, i); 180 FileObject[] sRoots = SourceForBinaryQuery.findSourceRoots 181 (root.getURL ()).getRoots (); 182 ClassPath sourcePath = ClassPathSupport.createClassPath (sRoots); 183 FileObject rfo = sourcePath.findResource (resourceName + ".java"); 184 if (rfo == null) return null; 185 return rfo.getURL ().toExternalForm (); 186 } catch (FileStateInvalidException ex) { 187 ex.printStackTrace (); 188 return null; 189 } 190 } 191 } 192 | Popular Tags |