1 19 20 package org.netbeans.modules.java; 21 22 import java.io.*; 23 24 import javax.swing.JEditorPane ; 25 import javax.swing.text.Document ; 26 import javax.swing.text.StyledDocument ; 27 import javax.swing.text.EditorKit ; 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 44 public abstract class IndentFileEntry extends FileEntry.Format { 45 private static final String NEWLINE = "\n"; private static final String EA_PREFORMATTED = "org-netbeans-modules-java-preformattedSource"; 48 private ThreadLocal indentEngine; 49 50 51 IndentFileEntry(MultiDataObject dobj, FileObject file) { 52 super(dobj, file); 53 } 54 55 private EditorKit createEditorKit(String mimeType) { 56 return CloneableEditorSupport.getEditorKit(mimeType); 57 } 58 59 final void setIndentEngine(IndentEngine engine) { 60 synchronized (this) { 61 if (indentEngine == null) 62 indentEngine = new ThreadLocal (); 63 } 64 indentEngine.set(engine); 65 } 66 67 final void initializeIndentEngine() { 68 StyledDocument doc = createDocument(createEditorKit(getFile().getMIMEType())); 69 IndentEngine engine = IndentEngine.find(doc); setIndentEngine(engine); 71 } 72 73 private StyledDocument createDocument(EditorKit kit) { 74 Document doc = kit.createDefaultDocument(); 75 if (doc instanceof StyledDocument ) { 76 return (StyledDocument )doc; 77 } else { 78 return new org.openide.text.FilterDocument(doc); 79 } 80 } 81 82 85 public FileObject createFromTemplate (FileObject f, String name) throws IOException { 86 String ext = getFile ().getExt (); 87 String sep = System.getProperty("line.separator"); 89 if (name == null) { 90 name = FileUtil.findFreeFileName(f, getFile ().getName (), ext); 91 } 92 FileObject fo = f.createData (name, ext); 93 java.text.Format frm = createFormat (f, name, ext); 94 InputStream is=getFile ().getInputStream (); 95 String encoding = Util.getFileEncoding(getFile()); 96 Reader reader=encoding==null ? new InputStreamReader(is) : new InputStreamReader(is,encoding); 97 BufferedReader r = new BufferedReader (reader); 98 StyledDocument doc = createDocument(createEditorKit(fo.getMIMEType())); 99 IndentEngine eng = (IndentEngine)indentEngine.get(); 100 if (eng == null) eng = IndentEngine.find(doc); 101 Object attr = getFile().getAttribute(EA_PREFORMATTED); 102 boolean preformatted = false; 103 104 if (attr != null && attr instanceof Boolean ) { 105 preformatted = ((Boolean )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 line = null; 116 String current; 117 int offset = 0; 118 String text; 119 120 while ((current = r.readLine ()) != null) { 121 if (line != null) { 122 doc.insertString(offset, NEWLINE, null); 124 offset++; 125 } 126 line = frm.format (current); 127 128 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 e) { 140 } finally { 141 w.close (); 142 } 143 } finally { 144 lock.releaseLock (); 145 } 146 } finally { 147 r.close (); 148 } 149 FileUtil.copyAttributes (getFile (), fo); 151 fo.setAttribute(DataObject.PROP_TEMPLATE, null); 153 return fo; 154 } 155 156 static String fixupGuardedBlocks(String indentedLine) { 157 int offset = indentedLine.indexOf(JavaEditor.MAGIC_PREFIX); 158 if (offset == -1) 159 return indentedLine; 160 int firstLineEnd = indentedLine.indexOf('\n'); if (firstLineEnd == -1 || firstLineEnd > offset) 163 return indentedLine; 165 int guardedLineEnd = indentedLine.indexOf('\n', offset); StringBuffer sb = new StringBuffer (indentedLine.length()); 167 sb.append(indentedLine.substring(0, firstLineEnd)); 168 String 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()); if (isGuardLINE) { 177 guard = guard.replace("//GEN-LINE:", "//GEN-BEGIN:"); } 179 sb.append(guard); 180 sb.append(indentedLine.substring(firstLineEnd, offset)); 181 182 if (isGuardLINE) { 183 int colonIndex = guard.indexOf(':'); 184 String guardName = guard.substring(colonIndex + 1); 185 sb.append("//GEN-END:").append(guardName); } else { 187 boolean isGuardFIRST = guard.startsWith("FIRST:", JavaEditor.MAGIC_PREFIX.length()); if (isGuardFIRST) { 189 int colonIndex = guard.indexOf(':'); 190 String guardName = guard.substring(colonIndex + 1); 191 sb.append("//GEN-HEADEREND:").append(guardName); } 193 } 194 195 if (guardedLineEnd != -1) 196 sb.append(indentedLine.substring(guardedLineEnd)); 197 return sb.toString(); 198 } 199 200 public static String safeIndent(IndentEngine engine, String text, StyledDocument 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 ex) { 210 ErrorManager.getDefault().annotate( 211 ex, ErrorManager.WARNING, "Indentation engine error", Util.getString("EXMSG_IndentationEngineError"), ex, null); 213 ErrorManager.getDefault().notify(ex); 214 return text; 215 } 216 } 217 } 218 | Popular Tags |