View Javadoc

1   /*
2    * Copyright 2002 - 2007 JEuclid, http://jeuclid.sf.net
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  /* $Id: FileIO.java,v cca61eec2241 2008/05/23 09:53:47 maxberger $ */
18  
19  package net.sourceforge.jeuclid.app.mathviewer;
20  
21  import java.awt.FileDialog;
22  import java.awt.Frame;
23  import java.io.File;
24  import java.io.FilenameFilter;
25  import java.io.IOException;
26  import java.util.Set;
27  
28  import javax.swing.JFileChooser;
29  import javax.swing.JOptionPane;
30  
31  import net.sourceforge.jeuclid.MathMLParserSupport;
32  import net.sourceforge.jeuclid.MutableLayoutContext;
33  import net.sourceforge.jeuclid.converter.Converter;
34  import net.sourceforge.jeuclid.converter.ConverterRegistry;
35  
36  import org.apache.commons.logging.Log;
37  import org.apache.commons.logging.LogFactory;
38  import org.w3c.dom.Document;
39  import org.w3c.dom.Node;
40  import org.xml.sax.SAXException;
41  
42  /**
43   * File I/O support functionality for MathViewer.
44   * 
45   * @version $Revision: cca61eec2241 $
46   */
47  public final class FileIO {
48  
49      /**
50       * Logger for this class
51       */
52      private static final Log LOGGER = LogFactory.getLog(FileIO.class);
53  
54      private static final String EXPORT_ERROR = "MathViewer.exportError"; //$NON-NLS-1$,
55  
56      private File lastPath;
57  
58      private static final class SingletonHolder {
59          private static FileIO instance = new FileIO();
60  
61          private SingletonHolder() {
62          }
63      }
64  
65      private FileIO() {
66      }
67  
68      /**
69       * Retrieve the FileIO object.
70       * 
71       * @return the FileIO object
72       */
73      public static FileIO getInstance() {
74          return FileIO.SingletonHolder.instance;
75      }
76  
77      private static String getExtension(final String fileName) {
78          return fileName.substring(fileName.lastIndexOf('.') + 1);
79      }
80  
81      private static class SaveExportFilter implements FilenameFilter {
82  
83          private final Set<String> extensions;
84  
85          protected SaveExportFilter() {
86              this.extensions = ConverterRegistry.getInstance()
87                      .getAvailableExtensions();
88          };
89  
90          public boolean accept(final File dir, final String name) {
91              return this.extensions.contains(FileIO.getExtension(name));
92          }
93      }
94  
95      /**
96       * Select a file.
97       * 
98       * @param parent
99       *            Frame of the parent
100      * @return A File or null.
101      */
102     public File selectFileToOpen(final Frame parent) {
103         final File selectedFile;
104 
105         if (MathViewer.OSX) {
106             // Have to use AWT file chooser for Mac-friendlyness
107             final FileDialog chooser = new FileDialog(parent,
108                     "Please select a MathML file");
109             if (this.lastPath != null) {
110                 chooser.setDirectory(this.lastPath.toString());
111             }
112             chooser.setVisible(true);
113             final String fileName = chooser.getFile();
114             if (fileName != null) {
115                 selectedFile = new File(chooser.getDirectory(), fileName);
116             } else {
117                 selectedFile = null;
118             }
119         } else {
120             final JFileChooser fc = new JFileChooser(this.lastPath);
121             final int returnVal = fc.showOpenDialog(parent);
122             if (returnVal == JFileChooser.APPROVE_OPTION) {
123                 selectedFile = fc.getSelectedFile();
124             } else {
125                 selectedFile = null;
126             }
127         }
128         if (selectedFile != null) {
129             this.lastPath = selectedFile.getParentFile();
130         }
131         return selectedFile;
132     }
133 
134     /**
135      * Load the given file.
136      * 
137      * @param selectedFile
138      *            File object to load.
139      * @param parent
140      *            Frame of parent window
141      * @return a parsed Document or null
142      */
143     public Document loadFile(final Frame parent, final File selectedFile) {
144         Document retVal;
145         if (selectedFile == null) {
146             retVal = null;
147         } else {
148             try {
149                 retVal = MathMLParserSupport.parseFile(selectedFile);
150             } catch (final SAXException e) {
151                 retVal = null;
152                 FileIO.LOGGER.warn(e.getMessage(), e);
153                 JOptionPane
154                         .showMessageDialog(
155                                 parent,
156                                 e.getMessage(),
157                                 Messages.getString("MathViewer.errorParsing"), JOptionPane.ERROR_MESSAGE); //$NON-NLS-1$
158             } catch (final IOException e) {
159                 retVal = null;
160                 FileIO.LOGGER.warn(e.getMessage(), e);
161                 JOptionPane
162                         .showMessageDialog(
163                                 parent,
164                                 e.getMessage(),
165                                 Messages
166                                         .getString("MathViewer.errorAccessing"), JOptionPane.ERROR_MESSAGE); //$NON-NLS-1$
167             }
168         }
169         return retVal;
170     }
171 
172     /**
173      * Save a document.
174      * 
175      * @param parent
176      *            frame of parent.
177      * @param document
178      *            the MML document to save.
179      * @param params
180      *            rendering parameters.
181      */
182     public void saveDocument(final Frame parent, final Node document,
183             final MutableLayoutContext params) {
184         final File selectedFile;
185 
186         if (MathViewer.OSX) {
187             // Have to use AWT file chooser for Mac-friendlyness
188             final FileDialog chooser = new FileDialog(parent, "Export to...",
189                     FileDialog.SAVE);
190             if (this.lastPath != null) {
191                 chooser.setDirectory(this.lastPath.toString());
192             }
193             chooser.setFilenameFilter(new SaveExportFilter());
194 
195             chooser.setVisible(true);
196             final String fileName = chooser.getFile();
197             if (fileName != null) {
198                 selectedFile = new File(chooser.getDirectory(), fileName);
199             } else {
200                 selectedFile = null;
201             }
202         } else {
203             final JFileChooser fc = new JFileChooser(this.lastPath);
204             final int returnVal = fc.showSaveDialog(parent);
205             if (returnVal == JFileChooser.APPROVE_OPTION) {
206                 selectedFile = fc.getSelectedFile();
207             } else {
208                 selectedFile = null;
209             }
210 
211         }
212         if (selectedFile != null) {
213             this.lastPath = selectedFile.getParentFile();
214 
215             FileIO.LOGGER.info(selectedFile);
216 
217             int doIt = JOptionPane.YES_OPTION;
218 
219             if (selectedFile.exists()) {
220                 doIt = JOptionPane.showConfirmDialog(parent, "File "
221                         + selectedFile.getName()
222                         + " already exists. Overwrite?", "Confirm Overwrite",
223                         JOptionPane.YES_NO_OPTION);
224             }
225 
226             if (doIt == JOptionPane.YES_OPTION) {
227                 this.exportAs(parent, selectedFile, document, params);
228             }
229         }
230     }
231 
232     private void exportAs(final Frame parent, final File selectedFile,
233             final Node document, final MutableLayoutContext params) {
234         final String fileName = selectedFile.getName();
235         final String extension = FileIO.getExtension(fileName);
236         final String mimetype = ConverterRegistry.getInstance()
237                 .getMimeTypeForSuffix(extension);
238         if (mimetype != null) {
239             try {
240                 if (Converter.getInstance().convert(document, selectedFile,
241                         mimetype, params) == null) {
242                     JOptionPane.showMessageDialog(parent,
243                             "Failed to write to " + fileName, Messages
244                                     .getString(FileIO.EXPORT_ERROR),
245                             JOptionPane.ERROR_MESSAGE);
246 
247                 }
248             } catch (final IOException e) {
249                 FileIO.LOGGER.warn(e);
250                 JOptionPane.showMessageDialog(parent, e.getMessage(),
251                         Messages.getString(FileIO.EXPORT_ERROR),
252                         JOptionPane.ERROR_MESSAGE);
253             }
254         } else {
255             JOptionPane.showMessageDialog(parent,
256                     "Unsupported file extension " + extension, Messages
257                             .getString(FileIO.EXPORT_ERROR),
258                     JOptionPane.ERROR_MESSAGE);
259 
260         }
261     }
262 
263 }