1 19 20 package org.netbeans.api.java.source; 21 22 import java.io.*; 23 import java.util.*; 24 import javax.swing.text.BadLocationException ; 25 import javax.swing.text.Document ; 26 import org.netbeans.editor.BaseDocument; 27 import org.openide.cookies.EditorCookie; 28 import org.openide.filesystems.FileObject; 29 import org.openide.filesystems.FileUtil; 30 import org.openide.loaders.DataObject; 31 import org.openide.text.PositionRef; 32 33 38 public final class ModificationResult { 39 40 private JavaSource js; 41 Map<FileObject, List<Difference>> diffs = new HashMap<FileObject, List<Difference>>(); 42 43 44 ModificationResult(final JavaSource js) { 45 this.js = js; 46 } 47 48 50 public Set<? extends FileObject> getModifiedFileObjects() { 51 return diffs.keySet(); 52 } 53 54 public List<? extends Difference> getDifferences(FileObject fo) { 55 return diffs.get(fo); 56 } 57 58 62 public void commit() throws IOException { 63 try { 64 for (Map.Entry<FileObject, List<Difference>> me : diffs.entrySet()) { 65 commit(me.getKey(), me.getValue(), null); 66 } 67 } finally { 68 if (this.js != null) { 69 this.js.revalidate(); 70 } 71 } 72 } 73 74 private void commit(FileObject fo, List<Difference> differences, Writer out) throws IOException { 75 DataObject dObj = DataObject.find(fo); 76 EditorCookie ec = dObj != null ? (EditorCookie) dObj.getCookie(EditorCookie.class) : null; 77 if (ec != null && out == null) { 81 Document doc = ec.getDocument(); 82 if (doc != null) { 83 if (doc instanceof BaseDocument) 84 ((BaseDocument)doc).atomicLock(); 85 try { 86 for (Difference diff : differences) { 87 if (diff.isExcluded()) 88 continue; 89 try { 90 switch (diff.getKind()) { 91 case INSERT: 92 doc.insertString(diff.getStartPosition().getOffset(), diff.getNewText(), null); 93 break; 94 case REMOVE: 95 doc.remove(diff.getStartPosition().getOffset(), diff.getEndPosition().getOffset() - diff.getStartPosition().getOffset()); 96 break; 97 case CHANGE: 98 doc.remove(diff.getStartPosition().getOffset(), diff.getEndPosition().getOffset() - diff.getStartPosition().getOffset()); 99 doc.insertString(diff.getStartPosition().getOffset(), diff.getNewText(), null); 100 break; 101 } 102 } catch (BadLocationException ex) { 103 IOException ioe = new IOException(); 104 ioe.initCause(ex); 105 throw ioe; 106 } 107 } 108 } finally { 109 if (doc instanceof BaseDocument) 110 ((BaseDocument)doc).atomicUnlock(); 111 } 112 return; 113 } 114 } 115 InputStream ins = null; 116 ByteArrayOutputStream baos = null; 117 Reader in = null; 118 try { 119 ins = fo.getInputStream(); 120 baos = new ByteArrayOutputStream(); 121 FileUtil.copy(ins, baos); 122 123 ins.close(); 124 ins = null; 125 byte[] arr = baos.toByteArray(); 126 baos.close(); 127 baos = null; 128 in = new InputStreamReader(new ByteArrayInputStream(arr)); 129 if (out == null) { 132 out = new OutputStreamWriter(fo.getOutputStream()); 133 } 134 int offset = 0; 135 for (Difference diff : differences) { 136 if (diff.isExcluded()) 137 continue; 138 int pos = diff.getStartPosition().getOffset(); 139 char[] buff = new char[pos - offset]; 140 int n; 141 if ((n = in.read(buff)) > 0) { 142 out.write(buff, 0, n); 143 offset += n; 144 } 145 switch (diff.getKind()) { 146 case INSERT: 147 out.write(diff.getNewText()); 148 break; 149 case REMOVE: 150 int len = diff.getEndPosition().getOffset() - diff.getStartPosition().getOffset(); 151 in.skip(len); 152 offset += len; 153 break; 154 case CHANGE: 155 len = diff.getEndPosition().getOffset() - diff.getStartPosition().getOffset(); 156 in.skip(len); 157 offset += len; 158 out.write(diff.getNewText()); 159 break; 160 } 161 } 162 char[] buff = new char[1024]; 163 int n; 164 while ((n = in.read(buff)) > 0) 165 out.write(buff, 0, n); 166 } finally { 167 if (ins != null) 168 ins.close(); 169 if (baos != null) 170 baos.close(); 171 if (in != null) 172 in.close(); 173 if (out != null) 174 out.close(); 175 } 176 } 177 178 186 public String getResultingSource(FileObject fileObject) throws IOException { 187 assert fileObject != null : "Provided fileObject is null"; 188 StringWriter writer = new StringWriter(); 189 commit(fileObject, diffs.get(fileObject), writer); 190 191 return writer.toString(); 192 } 193 194 public static final class Difference { 195 Kind kind; 196 PositionRef startPos; 197 PositionRef endPos; 198 String oldText; 199 String newText; 200 String description; 201 private boolean excluded; 202 203 Difference(Kind kind, PositionRef startPos, PositionRef endPos, String oldText, String newText, String description) { 204 this.kind = kind; 205 this.startPos = startPos; 206 this.endPos = endPos; 207 this.oldText = oldText; 208 this.newText = newText; 209 this.description = description; 210 this.excluded = false; 211 } 212 213 Difference(Kind kind, PositionRef startPos, PositionRef endPos, String oldText, String newText) { 214 this(kind, startPos, endPos, oldText, newText, null); 215 } 216 217 public Kind getKind() { 218 return kind; 219 } 220 221 public PositionRef getStartPosition() { 222 return startPos; 223 } 224 225 public PositionRef getEndPosition() { 226 return endPos; 227 } 228 229 public String getOldText() { 230 return oldText; 231 } 232 233 public String getNewText() { 234 return newText; 235 } 236 237 public boolean isExcluded() { 238 return excluded; 239 } 240 241 public void exclude(boolean b) { 242 excluded = b; 243 } 244 245 public String toString() { 246 return kind + "<" + startPos.getOffset() + ", " + endPos.getOffset() + ">: " + oldText + " -> " + newText; 247 } 248 public String getDescription() { 249 return description; 250 } 251 252 public static enum Kind { 253 INSERT, 254 REMOVE, 255 CHANGE 256 } 257 } 258 } 259 | Popular Tags |