KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > xml > core > actions > InputOutputReporter


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.xml.core.actions;
20
21 import java.beans.PropertyChangeEvent JavaDoc;
22 import java.beans.PropertyChangeListener JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.io.File JavaDoc;
25 import java.text.MessageFormat JavaDoc;
26 import java.util.*;
27 import java.net.*;
28
29 import org.openide.loaders.DataObject;
30 import org.openide.loaders.DataObjectNotFoundException;
31 import org.openide.text.Line;
32 import org.openide.filesystems.FileObject;
33 import org.openide.filesystems.FileUtil;
34 import org.openide.filesystems.FileStateInvalidException;
35 import org.openide.filesystems.URLMapper;
36 import org.openide.*;
37 import org.openide.nodes.*;
38 import org.openide.cookies.*;
39 import org.openide.windows.*;
40 import org.openide.util.WeakSet;
41
42 import org.xml.sax.SAXParseException JavaDoc;
43
44 import org.netbeans.api.xml.cookies.*;
45 import org.openide.text.Annotatable;
46 import org.openide.text.Annotation;
47
48 /**
49  * Provides InputOutput UI for CheckXMLCookie.
50  * <p>
51  * Implementation: <code>display</code> method samples <code>Line</code> where error occured so
52  * further modifications (fixes) do not affect it and installs a InputOutput
53  * line handler for SAXParseErrors.
54  *
55  * @author Petr Kuzel
56  * @see InputOutput
57  * @deprecated XML tools actions API candidate
58  */

59 public final class InputOutputReporter implements CookieObserver {
60
61     //0 extends message, 1 line number, 2 url of external entity
62
private final String JavaDoc FORMAT = "{0} [{1}] {2}"; // NOI18N
63

64     private String JavaDoc ioName;
65
66     private DataObject dataObject;
67
68     // remember all attached annotations
69
private static final Set hyperlinks =
70         Collections.synchronizedSet(new WeakSet()); // Set<Hyperlink>
71

72     /**
73      * Creates new InputOutputReporter regirecting ProcessorListener
74      * to InputOutput. To finish per call initialization setNode()
75      * must be called.
76      */

77     public InputOutputReporter() {
78         this(Util.THIS.getString("TITLE_XML_check_window"));
79     }
80
81     public InputOutputReporter(String JavaDoc name) {
82         initInputOutput(name);
83     }
84
85     /**
86      * Somehow helps to properly link to external entities.
87      * XXX But actual test case is not know.
88      */

89     public void setNode(Node node) {
90         if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug ("InputOutputReporter.setNode: " + node, new RuntimeException JavaDoc ("Who calls InputOutputReporter.setNode"));
91
92         dataObject = (DataObject) node.getCookie(DataObject.class);
93     }
94     
95     /**
96      * Associated data object accessor
97      */

98     private DataObject dataObject() {
99         return dataObject;
100     }
101
102     public void receive(CookieMessage msg) {
103         Object JavaDoc detail = msg.getDetail(XMLProcessorDetail.class);
104
105         if ( Util.THIS.isLoggable() ) /* then */ {
106             Util.THIS.debug ("InputOutputReporter.receive:");
107             Util.THIS.debug (" dataObject = " + dataObject);
108             Util.THIS.debug (" Message = " + msg);
109             Util.THIS.debug (" detail = " + detail);
110             if ( detail == null ) {
111                 Util.THIS.debug (new RuntimeException JavaDoc ("Message's Detail is _null_!!!"));
112             }
113         }
114
115         if (detail instanceof XMLProcessorDetail) {
116             display(dataObject(), msg.getMessage(), (XMLProcessorDetail) detail);
117         } else {
118             message(msg.getMessage());
119         }
120     }
121     
122     
123     /**
124      * Display plain message in output window.
125      */

126     public void message(String JavaDoc message) {
127         out().println(message);
128     }
129     
130     /**
131      * Try to move InputOutput to front. Suitable for first message.
132      */

133     public final void moveToFront() {
134         moveToFront(false);
135     }
136
137     /**
138      * Try to move InputOUtput to front. Suitable for first and last messages.
139      * @param lastMessage if true close OutputWriter relation
140      */

141     public final void moveToFront(boolean lastMessage) {
142         boolean wasFocusTaken = tab().isFocusTaken();
143         tab().select();
144         tab().setFocusTaken(true);
145         out().write("\r");
146         tab().setFocusTaken(wasFocusTaken);
147         if (lastMessage) {
148             out().close();
149         }
150     }
151
152     /** Show using SAX parser error format */
153     private void display(DataObject dobj, String JavaDoc message, XMLProcessorDetail detail) {
154         // resolve actual data object that caused exception
155
// it may differ from XML document for external entities
156

157         DataObject actualDataObject = null;
158         try {
159             String JavaDoc systemId = detail.getSystemId();
160             URL url = new URL (systemId);
161             FileObject fos = URLMapper.findFileObject(url);
162             if (fos != null) {
163                 actualDataObject = DataObject.find(fos);
164             }
165
166             if ( Util.THIS.isLoggable() ) /* then */ {
167                 Util.THIS.debug ("InputOutputReporter.display: " + message);
168                 Util.THIS.debug (" systemId = " + detail.getSystemId());
169                 Util.THIS.debug (" url = " + url);
170                 Util.THIS.debug (" fos = " + fos);
171             }
172         } catch (MalformedURLException ex) {
173             // we test for null
174
if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug (ex);
175         } catch (DataObjectNotFoundException ex) {
176             // we test for null
177
if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug (ex);
178         }
179
180         // external should contain systemID for unresolned external entities
181

182         String JavaDoc external = ""; // NOI18N
183

184         if (actualDataObject == null) {
185             external = detail.getSystemId();
186         }
187         
188         
189         display (
190             actualDataObject, message, external,
191             detail.getLineNumber(),
192             detail.getColumnNumber()
193         );
194     }
195
196
197     /** Show it in output tab formatted and with attached controller. */
198     private void display(DataObject dobj, String JavaDoc message, String JavaDoc ext, int line, int col) {
199         
200         String JavaDoc text = null;
201         if (line >= 0) {
202             Object JavaDoc[] args = new Object JavaDoc[] {
203                                 message,
204                                 new Integer JavaDoc(line),
205                                 ext
206                             };
207
208             text = MessageFormat.format(FORMAT, args);
209         } else {
210             // unknown line so attach controller to file only
211
text = message;
212         }
213
214         if (dobj == null) {
215             out().println(text); // print without controller
216
} else {
217             try {
218                 Hyperlink ec = new Hyperlink (
219                     text,
220                     dobj,
221                     Math.max(line - 1, 0),
222                     Math.max(col - 1, 0)
223                 );
224                 out().println(text, ec);
225             } catch (IOException JavaDoc catchIt) {
226                 out().println(text); // print without controller
227
}
228         }
229     }
230
231     /** Set output writer used by this displayer.
232     * Share existing, clear content on reuse.
233     */

234     private void initInputOutput (String JavaDoc name) {
235         ioName = name;
236         tab().setFocusTaken (false);
237
238         // clear previous output
239
try {
240             out().reset();
241         } catch (IOException JavaDoc e) {
242             ErrorManager.getDefault().notify(e);
243         }
244     }
245
246     private OutputWriter out() {
247         return tab().getOut();
248     }
249
250     private InputOutput tab() {
251         return IOProvider.getDefault().getIO(ioName, false);
252     }
253
254     /**
255      * Release all annotations attached by this class
256      */

257     public static void releaseAllAnnotations() {
258         synchronized (hyperlinks) {
259             Iterator it = hyperlinks.iterator();
260             while (it.hasNext()) {
261                 ((Hyperlink)it.next()).detach();
262             }
263             hyperlinks.clear();
264         }
265     }
266             
267     private static class Hyperlink extends Annotation implements OutputListener, PropertyChangeListener JavaDoc {
268         
269         /** sampled line containing the error */
270         private Line xline;
271
272         /** original column with the err or -1 */
273         private int column;
274
275         private final String JavaDoc message;
276         
277         public Hyperlink (String JavaDoc message, DataObject data, int line, int column) throws IOException JavaDoc {
278             this.column = column;
279             this.message = message;
280             LineCookie cookie = (LineCookie)data.getCookie(LineCookie.class);
281             if (cookie == null) {
282                 throw new java.io.FileNotFoundException JavaDoc ();
283             } else {
284                 xline = cookie.getLineSet ().getCurrent(line);
285             }
286         }
287
288         public void outputLineSelected (OutputEvent ev) {
289             try {
290                 markError();
291                 show (Line.SHOW_TRY_SHOW);
292             } catch (IndexOutOfBoundsException JavaDoc ex) {
293             } catch (ClassCastException JavaDoc ex) {
294                 // This is hack because of CloneableEditorSupport error -- see CloneableEditorSupport:1193
295
}
296         }
297
298         public void outputLineAction (OutputEvent ev) {
299             try {
300                 markError();
301                 show(Line.SHOW_GOTO);
302             } catch (IndexOutOfBoundsException JavaDoc ex) {
303             } catch (ClassCastException JavaDoc ex) {
304                 // This is hack because of CloneableEditorSupport error -- see CloneableEditorSupport:1193
305
}
306         }
307
308         public void outputLineCleared (OutputEvent ev) {
309             hyperlinks.remove(this);
310             detach();
311         }
312         
313         protected void notifyDetached(Annotatable ann) {
314             ann.removePropertyChangeListener(this);
315         }
316
317         protected void notifyAttached(Annotatable ann) {
318             ann.addPropertyChangeListener(this);
319         }
320         
321         /**
322          * Prepare annotation target
323          */

324         private Annotatable createAnnotatable() {
325 // if (column < 1 ) {
326
return xline;
327 // } else {
328
// I have never got proper property changes on Line.Part
329
// return xline.createPart(0, column - 1);
330
// }
331
}
332         
333         // open document in editor
334
private void show(int mode) {
335             if (column == -1) {
336                 xline.show(mode);
337             } else {
338                 xline.show(mode, column);
339             }
340         }
341         
342         // we need to have one error at time
343
private void markError() {
344             releaseAllAnnotations();
345             hyperlinks.add(this);
346             attach(createAnnotatable());
347         }
348         
349         /**
350          * Returns name of the file which describes the annotation type.
351          * The file must be defined in module installation layer in the
352          * directory "Editors/AnnotationTypes"
353          */

354         public String JavaDoc getAnnotationType() {
355             return "org-netbeans-modules-xml-core-error"; // NOI18N
356
}
357         
358         /**
359          * Returns the tooltip text for this annotation.
360          */

361         public String JavaDoc getShortDescription() {
362             return message;
363         }
364         
365         // Affected line has changed.
366
public void propertyChange(PropertyChangeEvent JavaDoc ev) {
367             String JavaDoc prop = ev.getPropertyName();
368             if (prop == null ||
369                     prop.equals(Annotatable.PROP_TEXT) ||
370                     prop.equals(Annotatable.PROP_DELETED)) {
371                 // Assume user has edited & corrected the error (or at least we do
372
// nok know error column position anymore).
373
column = -1;
374                 hyperlinks.remove(this);
375                 detach();
376             }
377         }
378     }
379
380 }
381
Popular Tags