KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > editor > guards > GuardedSectionsImpl


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.editor.guards;
21
22 import java.io.IOException JavaDoc;
23 import java.io.InputStream JavaDoc;
24 import java.io.OutputStream JavaDoc;
25 import java.io.OutputStreamWriter JavaDoc;
26 import java.io.Reader JavaDoc;
27 import java.io.UnsupportedEncodingException JavaDoc;
28 import java.io.Writer JavaDoc;
29 import java.util.ArrayList JavaDoc;
30 import java.util.HashMap JavaDoc;
31 import java.util.List JavaDoc;
32 import java.util.Map JavaDoc;
33 import java.util.Set JavaDoc;
34 import java.util.TreeSet JavaDoc;
35 import java.util.logging.Level JavaDoc;
36 import java.util.logging.Logger JavaDoc;
37 import javax.swing.text.BadLocationException JavaDoc;
38 import javax.swing.text.Document JavaDoc;
39 import javax.swing.text.Position JavaDoc;
40 import javax.swing.text.StyledDocument JavaDoc;
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 /**
50  *
51  * @author Jan Pokorsky
52  */

53 public final class GuardedSectionsImpl {
54     /** Table of the guarded sections. Keys are the names of the sections
55     * and values are the GuardedSection classes. The table is null till
56     * while document is not in the memory.
57     */

58     Map JavaDoc<String JavaDoc, GuardedSectionImpl> sections = new HashMap JavaDoc<String JavaDoc, GuardedSectionImpl>(10);
59
60     final GuardedEditorSupport editor;
61     
62     private NewLine newLineType;
63     
64     /** Creates a new instance of GuardedDocument */
65     public GuardedSectionsImpl(GuardedEditorSupport ces) {
66         this.editor = ces;
67     }
68     
69     public Reader JavaDoc createGuardedReader(AbstractGuardedSectionsProvider gr, InputStream JavaDoc stream, String JavaDoc encoding) throws UnsupportedEncodingException JavaDoc {
70         GuardedReader greader = new GuardedReader(gr, stream, false, encoding, this);
71         
72         Document JavaDoc 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 JavaDoc createGuardedWriter(AbstractGuardedSectionsProvider gw, OutputStream JavaDoc stream, String JavaDoc encoding) throws UnsupportedEncodingException JavaDoc {
81         OutputStream JavaDoc os = new NewLineOutputStream(stream, newLineType);
82         if (sections != null) {
83             List JavaDoc<GuardedSection> list = new ArrayList JavaDoc<GuardedSection>(getGuardedSections());
84             if (list.size() > 0) {
85                 GuardedWriter writer = new GuardedWriter(gw, os, list, encoding);
86                 return writer;
87             }
88         }
89         Writer JavaDoc w;
90         if (encoding == null)
91             w = new OutputStreamWriter JavaDoc(os);
92         else
93             w = new OutputStreamWriter JavaDoc(os, encoding);
94         return w;
95         
96     }
97     
98     public StyledDocument JavaDoc getDocument() {
99         return this.editor.getDocument();
100     }
101
102     /** Try to find the section of the given name.
103     * @param name the name of the looked-for section
104     * @return the found guarded section or <code>null</code> if there is no section
105     * of the given name
106     */

107     public GuardedSection findSection(String JavaDoc name) {
108         StyledDocument JavaDoc 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 JavaDoc<GuardedSection> getGuardedSections() {
119         StyledDocument JavaDoc doc = this.editor.getDocument();
120         synchronized(this.sections) {
121             Set JavaDoc<GuardedSection> sortedGuards = new TreeSet JavaDoc<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 JavaDoc name, PositionBounds bounds) {
130         return (SimpleSection) createSimpleSectionImpl(name, bounds).guard;
131     }
132     
133     public InteriorSection createInteriorSectionObject(String JavaDoc name, PositionBounds header, PositionBounds body, PositionBounds footer) {
134         return (InteriorSection) createInteriorSectionImpl(name, header, body, footer).guard;
135     }
136
137     public SimpleSection createSimpleSection(Position JavaDoc pos, String JavaDoc name) throws BadLocationException JavaDoc {
138         checkNewSection(pos, name);
139         return doCreateSimpleSection(pos, name);
140     }
141
142     public InteriorSection createInteriorSection(Position JavaDoc pos, String JavaDoc name) throws BadLocationException JavaDoc {
143         checkNewSection(pos, name);
144         return doCreateInteriorSection(pos, name);
145     }
146     
147     private SimpleSection doCreateSimpleSection(final Position JavaDoc pos, final String JavaDoc name)
148         throws /*IllegalArgumentException,*/ BadLocationException JavaDoc {
149         
150         StyledDocument JavaDoc loadedDoc = null;
151         loadedDoc = this.editor.getDocument();
152         final StyledDocument JavaDoc doc = loadedDoc;
153         final SimpleSectionImpl[] sect = new SimpleSectionImpl[1];
154         final BadLocationException JavaDoc[] blex = new BadLocationException JavaDoc[1];
155         
156         NbDocument.runAtomic(doc, new Runnable JavaDoc() {
157             public void run() {
158                 try {
159                     int where = pos.getOffset();
160                     doc.insertString(where, "\n \n", null); // NOI18N
161
sect[0] = createSimpleSectionImpl(name, PositionBounds.create(where + 1, where + 2, GuardedSectionsImpl.this));
162                     sect[0].markGuarded(doc);
163                 } catch (BadLocationException JavaDoc 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 JavaDoc) new BadLocationException JavaDoc(
176                     "wrong offset", blex[0].offsetRequested() // NOI18N
177
).initCause(blex[0]);
178         }
179
180     }
181     
182     /** Create new interior guarded section at a specified place.
183      * @param pos section to create the new one after
184      * @param name the name of the new section
185      * @exception IllegalArgumentException if the name is already in use
186      * @exception BadLocationException if it is not possible to create a
187      * new guarded section here
188      */

189     private InteriorSection doCreateInteriorSection(final Position JavaDoc pos,
190             final String JavaDoc name)
191             throws IllegalArgumentException JavaDoc, BadLocationException JavaDoc {
192         StyledDocument JavaDoc loadedDoc = null;
193         loadedDoc = this.editor.getDocument();
194         
195         final StyledDocument JavaDoc doc = loadedDoc;
196         final InteriorSectionImpl[] sect = new InteriorSectionImpl[1];
197         final BadLocationException JavaDoc[] blex = new BadLocationException JavaDoc[1];
198         
199         NbDocument.runAtomic(doc, new Runnable JavaDoc() {
200             public void run() {
201                 try {
202                     int where = pos.getOffset();
203                     doc.insertString(where, "\n \n \n \n", null); // NOI18N
204
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 JavaDoc 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 JavaDoc) new BadLocationException JavaDoc(
225                     "wrong offset", blex[0].offsetRequested() // NOI18N
226
).initCause(blex[0]);
227         }
228     }
229     
230     // package
231

232     /** Takes the section descriptors from the GuardedReader and
233     * fills the table 'sections', also marks as guarded all sections
234     * in the given document.
235     * @param is Where to take the guarded section descriptions.
236     * @param doc Where to mark guarded.
237     */

238     void fillSections(List JavaDoc<GuardedSection> l, NewLine newLineType) {
239         this.newLineType = newLineType;
240         // XXX this should invalidate removed GS instances
241
// XXX maybe would be useful to map new list to old list to keep track of valid instances as much as possible
242
// XXX synchronize
243
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 JavaDoc doc = getDocument();
251                 gsi.markGuarded(doc);
252             } catch (BadLocationException JavaDoc ex) {
253                 Logger.getLogger(GuardedSectionsImpl.class.getName()).log(Level.SEVERE, ex.getLocalizedMessage(), ex);
254             }
255         }
256     }
257
258     // private
259

260     private SimpleSectionImpl createSimpleSectionImpl(String JavaDoc 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 JavaDoc 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 JavaDoc p, String JavaDoc name) {
276         synchronized (sections) {
277             checkOverlap(p);
278             GuardedSectionImpl gs = sections.get(name);
279             if (gs != null) {
280                 throw new IllegalArgumentException JavaDoc("name exists"); // NOI18N
281
}
282         }
283     }
284     
285     private void checkOverlap(Position JavaDoc p) throws IllegalArgumentException JavaDoc {
286         for (GuardedSectionImpl gs: this.sections.values()) {
287             if (gs.contains(p, false))
288                 throw new IllegalArgumentException JavaDoc("Sections overlap"); // NOI18N
289
}
290     }
291     
292     /** This stream is used for changing the new line delimiters.
293      * It replaces the '\n' by '\n', '\r' or "\r\n"
294      */

295     private static class NewLineOutputStream extends OutputStream JavaDoc {
296         /** Underlying stream. */
297         OutputStream JavaDoc stream;
298         
299         /** The type of new line delimiter */
300         NewLine newLineType;
301         
302         /** Creates new stream.
303          * @param stream Underlaying stream
304          * @param newLineType The type of new line delimiter
305          */

306         public NewLineOutputStream(OutputStream JavaDoc stream, NewLine newLineType) {
307             this.stream = stream;
308             this.newLineType = newLineType;
309         }
310         
311         /** Write one character.
312          * @param b char to write.
313          */

314         public void write(int b) throws IOException JavaDoc {
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 JavaDoc {
332             super.close();
333             this.stream.close();
334         }
335
336         public void flush() throws IOException JavaDoc {
337             this.stream.flush();
338         }
339     }
340     
341 }
342
Popular Tags