KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > java > IndentFileEntry


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.modules.java;
21
22 import java.io.*;
23
24 import javax.swing.JEditorPane JavaDoc;
25 import javax.swing.text.Document JavaDoc;
26 import javax.swing.text.StyledDocument JavaDoc;
27 import javax.swing.text.EditorKit JavaDoc;
28
29 import org.openide.ErrorManager;
30 import org.openide.filesystems.FileObject;
31 import org.openide.filesystems.FileLock;
32 import org.openide.filesystems.FileUtil;
33 import org.openide.loaders.DataObject;
34 import org.openide.loaders.MultiDataObject;
35 import org.openide.loaders.FileEntry;
36 import org.openide.text.CloneableEditorSupport;
37 import org.openide.text.IndentEngine;
38
39 /**
40  *
41  * @author Svata
42  * @version 1.0
43  */

44 public abstract class IndentFileEntry extends FileEntry.Format {
45     private static final String JavaDoc NEWLINE = "\n"; // NOI18N
46
private static final String JavaDoc EA_PREFORMATTED = "org-netbeans-modules-java-preformattedSource"; // NOI18N
47

48     private ThreadLocal JavaDoc indentEngine;
49     
50     /** Creates new JavaFileEntry */
51     IndentFileEntry(MultiDataObject dobj, FileObject file) {
52         super(dobj, file);
53     }
54
55     private EditorKit JavaDoc createEditorKit(String JavaDoc mimeType) {
56         return CloneableEditorSupport.getEditorKit(mimeType);
57     }
58     
59     /* package private */ final void setIndentEngine(IndentEngine engine) {
60         synchronized (this) {
61             if (indentEngine == null)
62                 indentEngine = new ThreadLocal JavaDoc();
63         }
64         indentEngine.set(engine);
65     }
66     
67     /* package private */ final void initializeIndentEngine() {
68         StyledDocument JavaDoc doc = createDocument(createEditorKit(getFile().getMIMEType()));
69         IndentEngine engine = IndentEngine.find(doc); // NOI18N
70
setIndentEngine(engine);
71     }
72
73     private StyledDocument JavaDoc createDocument(EditorKit JavaDoc kit) {
74         Document JavaDoc doc = kit.createDefaultDocument();
75         if (doc instanceof StyledDocument JavaDoc) {
76             return (StyledDocument JavaDoc)doc;
77         } else {
78             return new org.openide.text.FilterDocument(doc);
79         }
80     }
81     
82     /** Creates a new Java source from the template. Unlike the standard FileEntry.Format,
83         this indents the resulting text using an indentation engine.
84     */

85     public FileObject createFromTemplate (FileObject f, String JavaDoc name) throws IOException {
86         String JavaDoc ext = getFile ().getExt ();
87         String JavaDoc sep = System.getProperty("line.separator"); // NOI18N
88

89         if (name == null) {
90             name = FileUtil.findFreeFileName(f, getFile ().getName (), ext);
91         }
92         FileObject fo = f.createData (name, ext);
93         java.text.Format JavaDoc frm = createFormat (f, name, ext);
94         InputStream is=getFile ().getInputStream ();
95         String JavaDoc encoding = Util.getFileEncoding(getFile());
96         Reader reader=encoding==null ? new InputStreamReader(is) : new InputStreamReader(is,encoding);
97         BufferedReader r = new BufferedReader (reader);
98         StyledDocument JavaDoc doc = createDocument(createEditorKit(fo.getMIMEType()));
99         IndentEngine eng = (IndentEngine)indentEngine.get();
100         if (eng == null) eng = IndentEngine.find(doc);
101         Object JavaDoc attr = getFile().getAttribute(EA_PREFORMATTED);
102         boolean preformatted = false;
103         
104         if (attr != null && attr instanceof Boolean JavaDoc) {
105             preformatted = ((Boolean JavaDoc)attr).booleanValue();
106         }
107
108         try {
109             FileLock lock = fo.lock ();
110             try {
111                 encoding = Util.getFileEncoding(fo);
112                 OutputStream os=fo.getOutputStream(lock);
113                 OutputStreamWriter w = encoding==null ? new OutputStreamWriter(os) : new OutputStreamWriter(os, encoding);
114                 try {
115                     String JavaDoc line = null;
116                     String JavaDoc current;
117                     int offset = 0;
118                     String JavaDoc text;
119                     
120                     while ((current = r.readLine ()) != null) {
121                         if (line != null) {
122                             // newline between lines
123
doc.insertString(offset, NEWLINE, null);
124                             offset++;
125                         }
126                         line = frm.format (current);
127
128                         // partial indentation used only for pre-formatted sources
129
// see #19178 etc.
130
if (!preformatted || !line.equals(current)) {
131                             line = fixupGuardedBlocks(safeIndent(eng, line, doc, offset));
132                         }
133                         doc.insertString(offset, line, null);
134                             offset += line.length();
135                     }
136                     doc.insertString(doc.getLength(), NEWLINE, null);
137                     text=doc.getText(0, doc.getLength());
138                     w.write(text.replaceAll(NEWLINE,sep));
139                 } catch (javax.swing.text.BadLocationException JavaDoc e) {
140                 } finally {
141                     w.close ();
142                 }
143             } finally {
144                 lock.releaseLock ();
145             }
146         } finally {
147             r.close ();
148         }
149         // copy attributes
150
FileUtil.copyAttributes (getFile (), fo);
151     // hack to overcome package-private modifier in setTemplate(fo, boolean)
152
fo.setAttribute(DataObject.PROP_TEMPLATE, null);
153         return fo;
154     }
155     
156     static String JavaDoc fixupGuardedBlocks(String JavaDoc indentedLine) {
157         int offset = indentedLine.indexOf(JavaEditor.MAGIC_PREFIX);
158         if (offset == -1)
159             return indentedLine;
160         // move the guarded block at the end of the first line in the string
161
int firstLineEnd = indentedLine.indexOf('\n'); // NOI18N
162
if (firstLineEnd == -1 || firstLineEnd > offset)
163             // already on the first line.
164
return indentedLine;
165         int guardedLineEnd = indentedLine.indexOf('\n', offset); // NOI18N
166
StringBuffer JavaDoc sb = new StringBuffer JavaDoc(indentedLine.length());
167         sb.append(indentedLine.substring(0, firstLineEnd));
168         String JavaDoc guard;
169         if (guardedLineEnd != -1) {
170             guard = indentedLine.substring(offset, guardedLineEnd);
171         } else {
172             guard = indentedLine.substring(offset);
173         }
174         
175         boolean isGuardLINE = guard.startsWith("LINE:", JavaEditor.MAGIC_PREFIX.length()); // NOI18N
176
if (isGuardLINE) {
177             guard = guard.replace("//GEN-LINE:", "//GEN-BEGIN:"); // NOI18N
178
}
179         sb.append(guard);
180         sb.append(indentedLine.substring(firstLineEnd, offset));
181
182         if (isGuardLINE) {
183             int colonIndex = guard.indexOf(':');
184             String JavaDoc guardName = guard.substring(colonIndex + 1);
185             sb.append("//GEN-END:").append(guardName); // NOI18N
186
} else {
187             boolean isGuardFIRST = guard.startsWith("FIRST:", JavaEditor.MAGIC_PREFIX.length()); // NOI18N
188
if (isGuardFIRST) {
189                 int colonIndex = guard.indexOf(':');
190                 String JavaDoc guardName = guard.substring(colonIndex + 1);
191                 sb.append("//GEN-HEADEREND:").append(guardName); // NOI18N
192
}
193         }
194         
195         if (guardedLineEnd != -1)
196             sb.append(indentedLine.substring(guardedLineEnd));
197         return sb.toString();
198     }
199
200     public static String JavaDoc safeIndent(IndentEngine engine, String JavaDoc text, StyledDocument JavaDoc doc, int offset) {
201         if (engine == null)
202             return text;
203         try {
204             StringWriter writer = new StringWriter();
205             Writer indentator = engine.createWriter(doc, offset, writer);
206             indentator.write(text);
207             indentator.close();
208             return writer.toString();
209         } catch (Exception JavaDoc ex) {
210         ErrorManager.getDefault().annotate(
211         ex, ErrorManager.WARNING, "Indentation engine error", // NOI18N
212
Util.getString("EXMSG_IndentationEngineError"), ex, null);
213             ErrorManager.getDefault().notify(ex);
214             return text;
215         }
216     }
217 }
218
Popular Tags