KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > retouche > source > parsing > SourceFileObject


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 package org.netbeans.modules.retouche.source.parsing;
20
21 import java.io.ByteArrayInputStream JavaDoc;
22 import java.io.ByteArrayOutputStream JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.io.InputStream JavaDoc;
25 import java.io.InputStreamReader JavaDoc;
26 import java.io.OutputStream JavaDoc;
27 import java.io.OutputStreamWriter JavaDoc;
28 import java.io.Reader JavaDoc;
29 import java.io.UnsupportedEncodingException JavaDoc;
30 import java.net.URI JavaDoc;
31 import java.nio.CharBuffer JavaDoc;
32 import java.util.Set JavaDoc;
33 import javax.swing.text.BadLocationException JavaDoc;
34 import javax.swing.text.Document JavaDoc;
35 import javax.swing.text.StyledDocument JavaDoc;
36 import org.netbeans.api.lexer.TokenHierarchy;
37 import org.netbeans.modules.gsf.Language;
38 import org.netbeans.modules.gsf.LanguageRegistry;
39 //import org.netbeans.api.lexer.TokenHierarchy;
40
import org.openide.ErrorManager;
41 import org.openide.cookies.EditorCookie;
42 import org.openide.filesystems.FileLock;
43 import org.openide.filesystems.FileObject;
44 import org.openide.filesystems.FileStateInvalidException;
45 import org.openide.loaders.DataObject;
46 import org.openide.loaders.DataObjectNotFoundException;
47 import org.openide.text.NbDocument;
48
49 /**
50  * This file is originally from Retouche, the Java Support
51  * infrastructure in NetBeans. I have modified the file as little
52  * as possible to make merging Retouche fixes back as simple as
53  * possible.
54  *
55  *
56  * @author Tomas Zezula
57  */

58 public class SourceFileObject/* implements DocumentProvider*/ {
59     
60     final FileObject file;
61 // private final Kind kind;
62
private URI JavaDoc uri; //Cache for URI
63
private String JavaDoc text;
64     private TokenHierarchy tokens;
65     
66     public static SourceFileObject create (final FileObject file) {
67         try {
68             return new SourceFileObject (file, false);
69         } catch (IOException JavaDoc ioe) {
70             ErrorManager.getDefault().notify(ioe);
71             return null;
72         }
73     }
74     
75     /** Creates a new instance of SourceFileObject */
76     public SourceFileObject (final FileObject file, final boolean renderNow) throws IOException JavaDoc {
77         assert file != null;
78         this.file = file;
79 // String ext = this.file.getExt();
80
// if (FileObjects.JAVA.equalsIgnoreCase(ext)) { //NOI18N
81
// this.kind = Kind.SOURCE;
82
// }
83
// else if (FileObjects.CLASS.equalsIgnoreCase(ext)) { //NOI18N
84
// this.kind = Kind.CLASS;
85
// }
86
// else if (FileObjects.HTML.equalsIgnoreCase(ext)) { //NOI18N
87
// this.kind = Kind.HTML;
88
// }
89
// else {
90
// this.kind = Kind.OTHER;
91
// }
92
if (renderNow) {
93             text = getCharContentImpl().toString();
94         }
95     }
96
97     
98
99 // public boolean isNameCompatible (String simplename, JavaFileObject.Kind kind) {
100
// assert simplename != null;
101
// return this.kind == kind && this.getNameWithoutExtension().equals(simplename);
102
// }
103

104     public CharBuffer JavaDoc getCharContent(boolean ignoreEncodingErrors) throws IOException JavaDoc {
105         String JavaDoc _text;
106         synchronized (this) {
107             _text = this.text;
108         }
109         if (_text != null) {
110             return CharBuffer.wrap(_text);
111         }
112         else {
113             return getCharContentImpl();
114         }
115     }
116     
117     public TokenHierarchy getTokenHiearchy() throws IOException JavaDoc {
118         if (tokens == null)
119             getCharContentImpl();
120         
121         return tokens;
122     }
123    
124
125     public java.io.Writer JavaDoc openWriter() throws IOException JavaDoc {
126         return new OutputStreamWriter JavaDoc (this.openOutputStream(),encodingName);
127     }
128
129     public Reader JavaDoc openReader(boolean ignoreEncodingErrors) throws IOException JavaDoc {
130         return new InputStreamReader JavaDoc (this.openInputStream(),encodingName);
131     }
132
133     static final String JavaDoc encodingName = new OutputStreamWriter JavaDoc(new ByteArrayOutputStream JavaDoc()).getEncoding();
134
135     public java.io.OutputStream JavaDoc openOutputStream() throws IOException JavaDoc {
136         final StyledDocument JavaDoc doc = getDocument(isOpened());
137         if (doc == null) {
138             return new LckStream (this.file);
139         }
140         else {
141             return new DocumentStream (doc);
142         }
143     }
144
145     public InputStream JavaDoc openInputStream() throws IOException JavaDoc {
146         String JavaDoc _text;
147         synchronized (this) {
148             _text = text;
149         }
150         if (_text != null) {
151             return new ByteArrayInputStream JavaDoc (_text.getBytes());
152         }
153         else {
154             final Document JavaDoc doc = getDocument(isOpened());
155             if (doc == null) {
156                 return this.file.getInputStream();
157             }
158             else {
159                 final StringBuilder JavaDoc builder = new StringBuilder JavaDoc ();
160                 doc.render(new Runnable JavaDoc() {
161                     public void run () {
162                       try {
163                             builder.append(doc.getText(0, doc.getLength()));
164                         } catch (BadLocationException JavaDoc e) {
165                             ErrorManager.getDefault().notify(e);
166                         }
167                     }
168                 });
169                 return new ByteArrayInputStream JavaDoc (builder.toString().getBytes());
170             }
171         }
172     }
173
174     public boolean delete() {
175         if (isModified()!=null) {
176             //If the file is modified in editor do not delete it
177
return false;
178         }
179         else {
180             try {
181                 FileLock lock = this.file.lock();
182                 try {
183                     this.file.delete (lock);
184                     return true;
185                 }
186                 finally {
187                     lock.releaseLock();
188                 }
189             } catch (IOException JavaDoc e) {
190                 return false;
191             }
192         }
193     }
194
195
196 // public JavaFileObject.Kind getKind() {
197
// return this.kind;
198
// }
199
//
200
public String JavaDoc getName() {
201        return this.file.getNameExt();
202     }
203
204     public String JavaDoc getNameWithoutExtension() {
205         return this.file.getName();
206     }
207     
208     public synchronized URI JavaDoc toUri () {
209         if (this.uri == null) {
210             try {
211                 this.uri = URI.create(this.file.getURL().toExternalForm());
212             } catch (FileStateInvalidException e) {
213                 ErrorManager.getDefault().notify(e);
214             }
215         }
216         return this.uri;
217     }
218
219     /**
220      * Returns the mtime of the file, in the case of opened
221      * modified file, the mtime is not known, this method returns
222      * the current time.
223      */

224     public long getLastModified() {
225         if (isModified()==null) {
226             return this.file.lastModified().getTime();
227         }
228         else {
229             return System.currentTimeMillis();
230         }
231     }
232     
233 // public NestingKind getNestingKind() {
234
// return null;
235
// }
236
//
237
// public Modifier getAccessLevel() {
238
// return null;
239
// }
240
//
241
// public @Override String toString () {
242
// return this.file.getPath();
243
// }
244

245     public @Override JavaDoc boolean equals (Object JavaDoc other) {
246         if (other instanceof SourceFileObject) {
247             SourceFileObject otherSource = (SourceFileObject) other;
248             return this.file.equals (otherSource.file);
249         }
250         else {
251             return false;
252         }
253     }
254     
255     public @Override JavaDoc int hashCode () {
256         return this.file.hashCode();
257     }
258     
259     public StyledDocument JavaDoc getDocument() {
260         EditorCookie ec = isOpened();
261         return ec != null ? getDocument(ec) : null;
262     }
263     
264     public void runAtomic(final Runnable JavaDoc r) {
265         assert r != null;
266         final StyledDocument JavaDoc doc = getDocument();
267         if (doc == null) {
268             throw new IllegalStateException JavaDoc ();
269         }
270         else {
271             NbDocument.runAtomic(doc,r);
272         }
273     }
274     
275     @SuppressWarnings JavaDoc ("unchecked") // NOI18N
276
private EditorCookie isModified () {
277         DataObject.Registry regs = DataObject.getRegistry();
278         Set JavaDoc<DataObject> modified = (Set JavaDoc<DataObject>) regs.getModifiedSet();
279         for (DataObject dobj : modified) {
280             if (this.file.equals(dobj.getPrimaryFile())) {
281                 EditorCookie ec = (EditorCookie) dobj.getCookie(EditorCookie.class);
282                 return ec;
283             }
284         }
285         return null;
286     }
287     
288     public EditorCookie isOpened () {
289         //if (this.kind == JavaFileObject.Kind.CLASS) {
290
// return null;
291
//}
292
try {
293             DataObject dobj = DataObject.find(this.file);
294             return (EditorCookie) dobj.getCookie(EditorCookie.class);
295         } catch (DataObjectNotFoundException dnf) {
296             return null;
297         }
298     }
299     
300     private CharBuffer JavaDoc getCharContentImpl () throws IOException JavaDoc {
301         final Document JavaDoc doc = getDocument(isOpened());
302         final char[][] result = new char[1][];
303         final int[] length = new int[1];
304         if (doc == null) {
305             Reader JavaDoc in = this.openReader (true);
306             int red = 0, rv;
307             try {
308                 int len = (int)this.file.getSize();
309                 result[0] = new char [len+1];
310                 while ((rv=in.read(result[0],red,len-red))>0 && (red=red+rv)<len);
311             } finally {
312                 in.close();
313             }
314             int j=0;
315             for (int i=0; i<red;i++) {
316                 if (result[0][i] =='\r') { //NOI18N
317
if (i+1>=red || result[0][i+1]!='\n') { //NOI18N
318
result[0][j++] = '\n'; //NOI18N
319
}
320                 }
321                 else {
322                     result[0][j++] = result[0][i];
323                 }
324             }
325             length[0] = j;
326         }
327         else {
328             doc.render(new Runnable JavaDoc() {
329                 public void run () {
330                   try {
331                         int len = doc.getLength();
332                         result[0] = new char[len+1];
333                         doc.getText(0,len).getChars(0,len,result[0],0);
334                         length[0] = len;
335                     } catch (BadLocationException JavaDoc e) {
336                         ErrorManager.getDefault().notify(e);
337                     }
338                 }
339             });
340         }
341         result[0][length[0]]='\n'; //NOI18N
342
CharBuffer JavaDoc charBuffer = CharBuffer.wrap (result[0],0,length[0]);
343         Language language = LanguageRegistry.getInstance().getLanguageByMimeType(this.file.getMIMEType());
344         if (language != null && language.getGsfLanguage() != null) {
345             org.netbeans.api.lexer.Language lexerLanguage = (org.netbeans.api.lexer.Language)language.getGsfLanguage().getLexerLanguage();
346             tokens = doc == null ? TokenHierarchy.create(charBuffer, true, lexerLanguage, null, null) : TokenHierarchy.get(doc);//TODO: .createSnapshot();
347
}
348         return charBuffer;
349     }
350             
351     private static StyledDocument JavaDoc getDocument (EditorCookie ec) {
352         return ec == null ? null : ec.getDocument();
353     }
354     
355     
356     private class LckStream extends OutputStream JavaDoc {
357         
358         private final OutputStream JavaDoc delegate;
359         private final FileLock lock;
360         
361         public LckStream (final FileObject fo) throws IOException JavaDoc {
362             assert fo != null;
363             this.lock = fo.lock();
364             try {
365                 this.delegate = fo.getOutputStream (this.lock);
366             } finally {
367                 if (this.delegate == null) {
368                     this.lock.releaseLock();
369                 }
370             }
371         }
372
373         public @Override JavaDoc void write(byte[] b, int off, int len) throws IOException JavaDoc {
374             this.delegate.write(b, off, len);
375         }
376
377         public @Override JavaDoc void write(byte[] b) throws IOException JavaDoc {
378             this.delegate.write(b);
379         }
380
381         public void write(int b) throws IOException JavaDoc {
382             this.delegate.write (b);
383         }
384
385         public @Override JavaDoc void close() throws IOException JavaDoc {
386             try {
387                 this.delegate.close();
388             } finally {
389                 this.lock.releaseLock();
390                 synchronized (SourceFileObject.this) {
391                     text = null;
392                 }
393             }
394         }
395     }
396     
397     private class DocumentStream extends OutputStream JavaDoc {
398         
399         private static final int BUF_SIZ=2048;
400         
401         private final StyledDocument JavaDoc doc;
402         private byte[] data;
403         private int pos;
404             
405         public DocumentStream (final StyledDocument JavaDoc doc) {
406             assert doc != null;
407             this.doc = doc;
408             this.data = new byte[BUF_SIZ];
409             this.pos = 0;
410         }
411         
412         public synchronized @Override JavaDoc void write(byte[] b, int off, int len) throws IOException JavaDoc {
413             ensureSize (len);
414             System.arraycopy(b,off,this.data,this.pos,len);
415             this.pos+=len;
416         }
417
418         public synchronized @Override JavaDoc void write(byte[] b) throws IOException JavaDoc {
419             ensureSize (b.length);
420             System.arraycopy(b,0,this.data,this.pos,b.length);
421             this.pos+=b.length;
422         }
423
424         public synchronized void write(int b) throws IOException JavaDoc {
425             ensureSize (1);
426             this.data[this.pos++]=(byte)(b&0xff);
427         }
428         
429         private void ensureSize (int delta) {
430             int requiredLength = this.pos + delta;
431             if (this.data.length<requiredLength) {
432                 int newSize = this.data.length + BUF_SIZ;
433                 while (newSize<requiredLength) {
434                     newSize+=BUF_SIZ;
435                 }
436                 byte[] newData = new byte[newSize];
437                 System.arraycopy(this.data,0,newData,0,this.pos);
438                 this.data = newData;
439             }
440         }
441         
442         public synchronized @Override JavaDoc void close() throws IOException JavaDoc {
443             try {
444                 NbDocument.runAtomic(this.doc,
445                     new Runnable JavaDoc () {
446                         public void run () {
447                             try {
448                                 doc.remove(0,doc.getLength());
449                                 doc.insertString(0,new String JavaDoc(data,0,pos,encodingName),null);
450                             } catch (BadLocationException JavaDoc e) {
451                                 ErrorManager.getDefault().notify(e);
452                             }
453                             catch (UnsupportedEncodingException JavaDoc ee) {
454                                 ErrorManager.getDefault().notify (ee);
455                             }
456                         }
457                     });
458             } finally {
459                 synchronized (SourceFileObject.this) {
460                     text = null;
461                 }
462             }
463         }
464     }
465 }
466
Popular Tags