KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > api > java > source > ModificationResult


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.api.java.source;
21
22 import java.io.*;
23 import java.util.*;
24 import javax.swing.text.BadLocationException JavaDoc;
25 import javax.swing.text.Document JavaDoc;
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 /**
34  * Class that collects changes built during a modification task run.
35  *
36  * @author Dusan Balek
37  */

38 public final class ModificationResult {
39
40     private JavaSource js;
41     Map<FileObject, List<Difference>> diffs = new HashMap<FileObject, List<Difference>>();
42     
43     /** Creates a new instance of ModificationResult */
44     ModificationResult(final JavaSource js) {
45         this.js = js;
46     }
47
48     // API of the class --------------------------------------------------------
49

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     /**
59      * Once all of the changes have been collected, this method can be used
60      * to commit the changes to the source files
61      */

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 editor cookie was found and user does not provided his own
78
// writer where he wants to see changes, commit the changes to
79
// found document.
80
if (ec != null && out == null) {
81             Document JavaDoc 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 JavaDoc 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             // initialize standard commit output stream, if user
130
// does not provide his own writer
131
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     /**
179      * Returned string represents preview of resulting source. No difference
180      * really is applied. Respects {@code isExcluded()} flag of difference.
181      *
182      * @param there can be more resulting source, user has to specify
183      * which wants to preview.
184      * @return if changes are applied source looks like return string
185      */

186     public String JavaDoc 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 JavaDoc oldText;
199         String JavaDoc newText;
200         String JavaDoc description;
201         private boolean excluded;
202
203         Difference(Kind kind, PositionRef startPos, PositionRef endPos, String JavaDoc oldText, String JavaDoc newText, String JavaDoc 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 JavaDoc oldText, String JavaDoc 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 JavaDoc getOldText() {
230             return oldText;
231         }
232         
233         public String JavaDoc 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 JavaDoc toString() {
246             return kind + "<" + startPos.getOffset() + ", " + endPos.getOffset() + ">: " + oldText + " -> " + newText;
247         }
248         public String JavaDoc getDescription() {
249             return description;
250         }
251         
252         public static enum Kind {
253             INSERT,
254             REMOVE,
255             CHANGE
256         }
257     }
258 }
259
Popular Tags