KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > pdf > LinkProcessor


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.pdf;
21
22 import java.awt.event.ActionEvent JavaDoc;
23 import java.awt.event.ActionListener JavaDoc;
24 import java.io.File JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.net.MalformedURLException JavaDoc;
27 import java.net.URI JavaDoc;
28 import java.net.URISyntaxException JavaDoc;
29 import java.net.URL JavaDoc;
30 import javax.swing.JMenuItem JavaDoc;
31 import org.openide.DialogDisplayer;
32 import org.openide.ErrorManager;
33 import org.openide.NotifyDescriptor;
34 import org.openide.awt.Mnemonics;
35 import org.openide.cookies.InstanceCookie;
36 import org.openide.filesystems.FileObject;
37 import org.openide.filesystems.FileUtil;
38 import org.openide.loaders.XMLDataObject;
39 import org.openide.modules.InstalledFileLocator;
40 import org.openide.util.NbBundle;
41 import org.w3c.dom.Document JavaDoc;
42 import org.w3c.dom.Element JavaDoc;
43 import org.w3c.dom.Node JavaDoc;
44 import org.w3c.dom.NodeList JavaDoc;
45
46
47 /**
48  * Permits a special kind of .xml file to be used for PDF links.
49  * After this processor is registered, any .xml file which matches
50  * the specified DTD (it must declare a <code>&lt;!DOCTYPE&gt;</code>)
51  * will provide an instance of a {@link JMenuItem}.
52  * This menu item will be named according to the XML file's display
53  * name (which may be controlled via localized filenames from a
54  * bundle as elsewhere).
55  * Selecting it will try to show the mentioned PDF file.
56  * The PDF file may be referred to as an absolute file name,
57  * or as a localized path within the IDE installation,
58  * or (in the future) as an arbitrary URL.
59  * The XML file is suitable for direct inclusion in a menu
60  * bar folder, for example <samp>..../system/Menu/Help/</samp>.
61  *
62  * @author Jesse Glick
63  * @author Marian Petras
64  * @see org.openide.loaders.XMLDataObject.Processor
65  */

66 public class LinkProcessor implements InstanceCookie,
67                                       XMLDataObject.Processor,
68                                       ActionListener JavaDoc {
69
70     /** Public ID of catalog. */
71     public static final String JavaDoc PUBLIC_ID
72             = "-//NetBeans//DTD PDF Document Menu Link 1.0//EN"; //NOI18N
73
/** */
74     public static final String JavaDoc PUBLIC_WWW
75             = "http://www.netbeans.org/dtds/pdf_link-1_0.dtd"; //NOI18N
76

77     /** <code>XMLDataObject</code> this processor is linked to. */
78     private XMLDataObject xmlDataObject;
79     
80     
81     /* JST: Replaced with registration in xml layer.
82     * Initilializes <code>LinkProcessor</code>. *
83     public static void init () {
84         // Registering of catalog is in xml layer, see org/netbeans/modules/utilities/Layer.xml.
85         
86         XMLDataObject.Info xmlInfo = new XMLDataObject.Info ();
87         
88         xmlInfo.setIconBase("/org/netbeans/modules/pdf/PDFDataIcon"); // NOI18N
89         xmlInfo.addProcessorClass(LinkProcessor.class);
90         XMLDataObject.registerInfo(PUBLIC_ID, xmlInfo);
91     }
92      */

93
94     /* Implements interface <code>XMLDataObject.Processor</code>. */
95     /**
96      * Attaches this processor to specified XML data object.
97      *
98      * @param xmlDataObject XML data object to which attach this processor
99      */

100     public void attachTo(XMLDataObject xmlDataObject) {
101         this.xmlDataObject = xmlDataObject;
102     }
103
104     /* Implements interface <code>InstanceCookie</code>. */
105     /**
106      * @return <code>JMenuItem</code> class
107      */

108     public Class JavaDoc instanceClass() throws IOException JavaDoc, ClassNotFoundException JavaDoc {
109         return JMenuItem JavaDoc.class;
110     }
111
112     /* Implements interface <code>InstanceCookie</code>. */
113     public Object JavaDoc instanceCreate() throws IOException JavaDoc, ClassNotFoundException JavaDoc {
114         /*
115         Image icon = Utilities.loadImage(
116                 "org/netbeans/modules/pdf/PDFDataIcon.gif"); //NOI18N
117         try {
118             FileObject file = xmlDataObject.getPrimaryFile();
119             FileSystem.Status fsStatus = file.getFileSystem().getStatus();
120             icon = fsStatus.annotateIcon(icon,
121                                          BeanInfo.ICON_COLOR_16x16,
122                                          xmlDataObject.files());
123         } catch (FileStateInvalidException fsie) {
124             // OK, so we use the default icon
125         } */

126             
127         String JavaDoc name = xmlDataObject.getNodeDelegate().getDisplayName();
128         
129         JMenuItem JavaDoc menuItem = new JMenuItem JavaDoc(/*new ImageIcon(icon)*/);
130         Mnemonics.setLocalizedText(menuItem, name);
131         menuItem.addActionListener(this);
132         
133         return menuItem;
134     }
135     
136     /* Implements interface <code>InstanceCookie</code>. */
137     /**
138      * @return name of the <code>xmlDataObject</code>
139      */

140     public String JavaDoc instanceName() {
141         return xmlDataObject.getName();
142     }
143
144     /**
145      * Retrieves the name of a file describing the XML data object
146      *
147      * @return as much precious path to the file as possible
148      */

149     private String JavaDoc getXMLFileName() {
150         FileObject fileObject = xmlDataObject.getPrimaryFile();
151         return FileUtil.getFileDisplayName(fileObject);
152     }
153
154     /**
155      * Notifies the user that the XML file is broken.
156      */

157     private void notifyXMLFileBroken() {
158         String JavaDoc msg = NbBundle.getMessage(LinkProcessor.class,
159                                          "EXC_file_not_matching_DTD", //NOI18N
160
getXMLFileName());
161         ErrorManager.getDefault().log(ErrorManager.USER, msg);
162     }
163     
164     /**
165      * Notifies the user about some problem with the XML file.
166      *
167      * @param msgKey resource bundle key for the message
168      * @param urlSpec url that caused the problem
169      * @param isError type of the message - use <code>true</code> for
170      * an error message, <code>false</code> for
171      * an information message
172      */

173     private void notifyBadFileSpec(String JavaDoc msgKey,
174                                    String JavaDoc urlSpec,
175                                    boolean isError) {
176         String JavaDoc msg = NbBundle.getMessage(LinkProcessor.class,
177                                          msgKey,
178                                          getXMLFileName(),
179                                          urlSpec);
180         ErrorManager.getDefault().log(isError ? ErrorManager.WARNING
181                                               : ErrorManager.USER,
182                                       msg);
183     }
184     
185     /**
186      */

187     private void notifyFileDoesNotExist(String JavaDoc path) {
188         String JavaDoc msg = NbBundle.getMessage(LinkProcessor.class,
189                                          "MSG_File_does_not_exist", //NOI18N
190
path);
191         DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(
192                 msg, NotifyDescriptor.WARNING_MESSAGE));
193     }
194     
195     /**
196      * Grabs a file from a specification in an element of an XML file.
197      *
198      * @param innerElement element containing specification of a PDF file
199      * @return file corresponding to the specification,
200      * or <code>null</code> if the specification was illegal
201      * or unsupported
202      */

203     private File JavaDoc grabFile(Element JavaDoc innerElement) {
204         String JavaDoc linkType = innerElement.getTagName();
205         
206         /* handle element "file": */
207         if (linkType.equals("file")) { //NOI18N
208
if (!innerElement.hasAttribute("path")) { //NOI18N
209
notifyXMLFileBroken();
210                 return null;
211             }
212             return new File JavaDoc(innerElement.getAttribute("path")); //NOI18N
213

214         /* handle element "idefile": */
215         } else if (linkType.equals("idefile")) { //NOI18N
216
if (!innerElement.hasAttribute("base")) { //NOI18N
217
notifyXMLFileBroken();
218                 return null;
219             }
220             String JavaDoc base = innerElement.getAttribute("base"); //NOI18N
221
String JavaDoc path = base.replace('.', '/') + ".pdf"; //NOI18N
222
File JavaDoc file = InstalledFileLocator.getDefault()
223                         .locate(path, null, true);
224             if (file == null) {
225                 notifyFileDoesNotExist(path);
226                 return null;
227             }
228             return file;
229             
230         /* handle element "url": */
231         } else if (linkType.equals("url")) { //NOI18N
232
if (!innerElement.hasAttribute("name")) { //NOI18N
233
notifyXMLFileBroken();
234                 return null;
235             }
236             String JavaDoc urlSpec = innerElement.getAttribute("name"); //NOI18N
237
URL JavaDoc url;
238             try {
239                 url = new URL JavaDoc(urlSpec);
240             } catch (MalformedURLException JavaDoc ex) {
241                 notifyBadFileSpec(
242                         "MSG_Cannot_open_malformed_URL", //NOI18N
243
urlSpec,
244                         true);
245                 return null;
246             }
247             if (!url.getProtocol().equals("file")) { //NOI18N
248
notifyBadFileSpec(
249                         "MSG_Cannot_open_unsupported_URL", //NOI18N
250
urlSpec,
251                         false);
252             }
253             try {
254                 return new File JavaDoc(new URI JavaDoc("file://" + url.getPath())); //NOI18N
255
} catch (URISyntaxException JavaDoc ex1) {
256                 ErrorManager.getDefault().notify(ex1);
257                 return null;
258             } catch (IllegalArgumentException JavaDoc ex2) {
259                 ErrorManager.getDefault().notify(ex2);
260                 return null;
261             }
262             
263         } else {
264             notifyXMLFileBroken();
265             return null;
266         }
267     }
268     
269     /* Implements interface <code>ActionListener</code>. */
270     /**
271      * Performs an action. Retrieves a PDF data object from the specified
272      * XML data object and opens it.
273      */

274     public void actionPerformed(ActionEvent JavaDoc evt) {
275         try {
276             
277             /* Grab the element containing the link: */
278             Element JavaDoc innerElement;
279             Document JavaDoc document = xmlDataObject.getDocument();
280             Element JavaDoc pdfLinkElement = document.getDocumentElement();
281             NodeList JavaDoc nodeList = pdfLinkElement.getChildNodes();
282             int count = nodeList.getLength();
283             Node JavaDoc node = null;
284             for (int i = 0; i < count; i++) {
285                 Node JavaDoc nextNode = nodeList.item(i);
286                 if (nextNode.getNodeType() == Node.ELEMENT_NODE) {
287                     if (node == null) {
288                         node = nextNode;
289                     } else {
290                         /* there should be just one element */
291                         notifyXMLFileBroken();
292                         return;
293                     }
294                 }
295             }
296             if (node == null) {
297                 /* there should be exactly one element within 'pdfLink' */
298                 notifyXMLFileBroken();
299                 return;
300             }
301             innerElement = (Element JavaDoc) node;
302             
303             /* Retrieve the PDF file: */
304             File JavaDoc file = grabFile(innerElement);
305             
306             /* Try to open the file in an external viewer: */
307             if (file != null) {
308                 try {
309                     // [PENDING] in-process PDF viewer support
310
new PDFOpenSupport(file).open();
311                     return;
312                 } catch (IllegalArgumentException JavaDoc ex) {
313                     notifyFileDoesNotExist(file.getPath());
314                 }
315             }
316         } catch (Exception JavaDoc e) {
317             ErrorManager.getDefault().notify(e);
318         }
319     }
320     
321 }
322
Popular Tags