1 19 20 package org.netbeans.modules.editor.guards; 21 22 import java.io.IOException ; 23 import java.io.InputStream ; 24 import java.io.OutputStream ; 25 import java.io.OutputStreamWriter ; 26 import java.io.Reader ; 27 import java.io.UnsupportedEncodingException ; 28 import java.io.Writer ; 29 import java.util.ArrayList ; 30 import java.util.HashMap ; 31 import java.util.List ; 32 import java.util.Map ; 33 import java.util.Set ; 34 import java.util.TreeSet ; 35 import java.util.logging.Level ; 36 import java.util.logging.Logger ; 37 import javax.swing.text.BadLocationException ; 38 import javax.swing.text.Document ; 39 import javax.swing.text.Position ; 40 import javax.swing.text.StyledDocument ; 41 import org.netbeans.api.editor.guards.GuardedSection; 42 import org.netbeans.api.editor.guards.GuardedSectionManager; 43 import org.netbeans.api.editor.guards.InteriorSection; 44 import org.netbeans.api.editor.guards.SimpleSection; 45 import org.netbeans.spi.editor.guards.GuardedEditorSupport; 46 import org.netbeans.spi.editor.guards.support.AbstractGuardedSectionsProvider; 47 import org.openide.text.NbDocument; 48 49 53 public final class GuardedSectionsImpl { 54 58 Map <String , GuardedSectionImpl> sections = new HashMap <String , GuardedSectionImpl>(10); 59 60 final GuardedEditorSupport editor; 61 62 private NewLine newLineType; 63 64 65 public GuardedSectionsImpl(GuardedEditorSupport ces) { 66 this.editor = ces; 67 } 68 69 public Reader createGuardedReader(AbstractGuardedSectionsProvider gr, InputStream stream, String encoding) throws UnsupportedEncodingException { 70 GuardedReader greader = new GuardedReader(gr, stream, false, encoding, this); 71 72 Document doc = getDocument(); 73 if (doc.getProperty(GuardedSectionManager.class) == null) { 74 GuardedSectionManager api = GuardsAccessor.DEFAULT.createGuardedSections(this); 75 doc.putProperty(GuardedSectionManager.class, api); 76 } 77 return greader; 78 } 79 80 public Writer createGuardedWriter(AbstractGuardedSectionsProvider gw, OutputStream stream, String encoding) throws UnsupportedEncodingException { 81 OutputStream os = new NewLineOutputStream(stream, newLineType); 82 if (sections != null) { 83 List <GuardedSection> list = new ArrayList <GuardedSection>(getGuardedSections()); 84 if (list.size() > 0) { 85 GuardedWriter writer = new GuardedWriter(gw, os, list, encoding); 86 return writer; 87 } 88 } 89 Writer w; 90 if (encoding == null) 91 w = new OutputStreamWriter (os); 92 else 93 w = new OutputStreamWriter (os, encoding); 94 return w; 95 96 } 97 98 public StyledDocument getDocument() { 99 return this.editor.getDocument(); 100 } 101 102 107 public GuardedSection findSection(String name) { 108 StyledDocument doc = this.editor.getDocument(); 109 synchronized(sections) { 110 GuardedSectionImpl gsi = sections.get(name); 111 if (gsi != null) { 112 return gsi.guard; 113 } 114 } 115 return null; 116 } 117 118 public Set <GuardedSection> getGuardedSections() { 119 StyledDocument doc = this.editor.getDocument(); 120 synchronized(this.sections) { 121 Set <GuardedSection> sortedGuards = new TreeSet <GuardedSection>(new GuardedPositionComparator()); 122 for (GuardedSectionImpl gsi: this.sections.values()) { 123 sortedGuards.add(gsi.guard); 124 } 125 return sortedGuards; 126 } 127 } 128 129 public SimpleSection createSimpleSectionObject(String name, PositionBounds bounds) { 130 return (SimpleSection) createSimpleSectionImpl(name, bounds).guard; 131 } 132 133 public InteriorSection createInteriorSectionObject(String name, PositionBounds header, PositionBounds body, PositionBounds footer) { 134 return (InteriorSection) createInteriorSectionImpl(name, header, body, footer).guard; 135 } 136 137 public SimpleSection createSimpleSection(Position pos, String name) throws BadLocationException { 138 checkNewSection(pos, name); 139 return doCreateSimpleSection(pos, name); 140 } 141 142 public InteriorSection createInteriorSection(Position pos, String name) throws BadLocationException { 143 checkNewSection(pos, name); 144 return doCreateInteriorSection(pos, name); 145 } 146 147 private SimpleSection doCreateSimpleSection(final Position pos, final String name) 148 throws BadLocationException { 149 150 StyledDocument loadedDoc = null; 151 loadedDoc = this.editor.getDocument(); 152 final StyledDocument doc = loadedDoc; 153 final SimpleSectionImpl[] sect = new SimpleSectionImpl[1]; 154 final BadLocationException [] blex = new BadLocationException [1]; 155 156 NbDocument.runAtomic(doc, new Runnable () { 157 public void run() { 158 try { 159 int where = pos.getOffset(); 160 doc.insertString(where, "\n \n", null); sect[0] = createSimpleSectionImpl(name, PositionBounds.create(where + 1, where + 2, GuardedSectionsImpl.this)); 162 sect[0].markGuarded(doc); 163 } catch (BadLocationException ex) { 164 blex[0] = ex; 165 } 166 } 167 }); 168 169 if (blex[0] == null) { 170 synchronized (this.sections) { 171 sections.put(name, sect[0]); 172 return (SimpleSection) sect[0].guard; 173 } 174 } else { 175 throw (BadLocationException ) new BadLocationException ( 176 "wrong offset", blex[0].offsetRequested() ).initCause(blex[0]); 178 } 179 180 } 181 182 189 private InteriorSection doCreateInteriorSection(final Position pos, 190 final String name) 191 throws IllegalArgumentException , BadLocationException { 192 StyledDocument loadedDoc = null; 193 loadedDoc = this.editor.getDocument(); 194 195 final StyledDocument doc = loadedDoc; 196 final InteriorSectionImpl[] sect = new InteriorSectionImpl[1]; 197 final BadLocationException [] blex = new BadLocationException [1]; 198 199 NbDocument.runAtomic(doc, new Runnable () { 200 public void run() { 201 try { 202 int where = pos.getOffset(); 203 doc.insertString(where, "\n \n \n \n", null); sect[0] = createInteriorSectionImpl( 205 name, 206 PositionBounds.create(where + 1, where + 2, GuardedSectionsImpl.this), 207 PositionBounds.createBodyBounds(where + 3, where + 4, GuardedSectionsImpl.this), 208 PositionBounds.create(where + 5, where + 6, GuardedSectionsImpl.this) 209 ); 210 sections.put(sect[0].getName(), sect[0]); 211 sect[0].markGuarded(doc); 212 } catch (BadLocationException ex) { 213 blex[0] = ex; 214 } 215 } 216 }); 217 218 if (blex[0] == null) { 219 synchronized (this.sections) { 220 sections.put(name, sect[0]); 221 return (InteriorSection) sect[0].guard; 222 } 223 } else { 224 throw (BadLocationException ) new BadLocationException ( 225 "wrong offset", blex[0].offsetRequested() ).initCause(blex[0]); 227 } 228 } 229 230 232 238 void fillSections(List <GuardedSection> l, NewLine newLineType) { 239 this.newLineType = newLineType; 240 this.sections.clear(); 244 245 for (GuardedSection gs: l) { 246 try { 247 GuardedSectionImpl gsi = GuardsAccessor.DEFAULT.getImpl(gs); 248 gsi.resolvePositions(); 249 sections.put(gs.getName(), gsi); 250 StyledDocument doc = getDocument(); 251 gsi.markGuarded(doc); 252 } catch (BadLocationException ex) { 253 Logger.getLogger(GuardedSectionsImpl.class.getName()).log(Level.SEVERE, ex.getLocalizedMessage(), ex); 254 } 255 } 256 } 257 258 260 private SimpleSectionImpl createSimpleSectionImpl(String name, PositionBounds bounds) { 261 SimpleSectionImpl sect = new SimpleSectionImpl(name, bounds, this); 262 GuardsAccessor.DEFAULT.createSimpleSection(sect); 263 return sect; 264 } 265 266 private InteriorSectionImpl createInteriorSectionImpl( 267 String name, PositionBounds header, PositionBounds body, PositionBounds footer) { 268 269 InteriorSectionImpl sect; 270 sect = new InteriorSectionImpl(name, header, body, footer, this); 271 GuardsAccessor.DEFAULT.createInteriorSection(sect); 272 return sect; 273 } 274 275 private void checkNewSection(Position p, String name) { 276 synchronized (sections) { 277 checkOverlap(p); 278 GuardedSectionImpl gs = sections.get(name); 279 if (gs != null) { 280 throw new IllegalArgumentException ("name exists"); } 282 } 283 } 284 285 private void checkOverlap(Position p) throws IllegalArgumentException { 286 for (GuardedSectionImpl gs: this.sections.values()) { 287 if (gs.contains(p, false)) 288 throw new IllegalArgumentException ("Sections overlap"); } 290 } 291 292 295 private static class NewLineOutputStream extends OutputStream { 296 297 OutputStream stream; 298 299 300 NewLine newLineType; 301 302 306 public NewLineOutputStream(OutputStream stream, NewLine newLineType) { 307 this.stream = stream; 308 this.newLineType = newLineType; 309 } 310 311 314 public void write(int b) throws IOException { 315 if (b == '\n') { 316 switch (newLineType) { 317 case R: 318 stream.write('\r'); 319 break; 320 case RN: 321 stream.write('\r'); 322 case N: 323 stream.write('\n'); 324 break; 325 } 326 } else { 327 stream.write(b); 328 } 329 } 330 331 public void close() throws IOException { 332 super.close(); 333 this.stream.close(); 334 } 335 336 public void flush() throws IOException { 337 this.stream.flush(); 338 } 339 } 340 341 } 342 | Popular Tags |