001    /**
002     * ========================================
003     * JFreeReport : a free Java report library
004     * ========================================
005     *
006     * Project Info:  http://reporting.pentaho.org/
007     *
008     * (C) Copyright 2000-2007, by Object Refinery Limited, Pentaho Corporation and Contributors.
009     *
010     * This library is free software; you can redistribute it and/or modify it under the terms
011     * of the GNU Lesser General Public License as published by the Free Software Foundation;
012     * either version 2.1 of the License, or (at your option) any later version.
013     *
014     * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
015     * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016     * See the GNU Lesser General Public License for more details.
017     *
018     * You should have received a copy of the GNU Lesser General Public License along with this
019     * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020     * Boston, MA 02111-1307, USA.
021     *
022     * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
023     * in the United States and other countries.]
024     *
025     * ------------
026     * $Id: HtmlZipExportDialog.java 3525 2007-10-16 11:43:48Z tmorgner $
027     * ------------
028     * (C) Copyright 2000-2005, by Object Refinery Limited.
029     * (C) Copyright 2005-2007, by Pentaho Corporation.
030     */
031    
032    package org.jfree.report.modules.gui.swing.html;
033    
034    import java.awt.BorderLayout;
035    import java.awt.Dialog;
036    import java.awt.Frame;
037    import java.awt.GridBagConstraints;
038    import java.awt.GridBagLayout;
039    import java.awt.GridLayout;
040    import java.awt.Insets;
041    import java.awt.event.ActionEvent;
042    import java.awt.event.KeyEvent;
043    import java.io.File;
044    import java.text.MessageFormat;
045    import java.util.ResourceBundle;
046    import javax.swing.AbstractAction;
047    import javax.swing.Action;
048    import javax.swing.ButtonGroup;
049    import javax.swing.JButton;
050    import javax.swing.JComponent;
051    import javax.swing.JFileChooser;
052    import javax.swing.JLabel;
053    import javax.swing.JOptionPane;
054    import javax.swing.JPanel;
055    import javax.swing.JRadioButton;
056    import javax.swing.JTextField;
057    import javax.swing.KeyStroke;
058    
059    import org.jfree.base.config.ModifiableConfiguration;
060    import org.jfree.io.IOUtils;
061    import org.jfree.report.flow.ReportJob;
062    import org.jfree.report.modules.gui.common.DefaultIconTheme;
063    import org.jfree.report.modules.gui.common.GuiContext;
064    import org.jfree.report.modules.gui.swing.common.AbstractExportDialog;
065    import org.jfree.report.modules.gui.swing.common.JStatusBar;
066    import org.jfree.report.modules.gui.swing.common.localization.JLabelLocaleUpdateHandler;
067    import org.jfree.ui.FilesystemFilter;
068    import org.jfree.ui.action.ActionButton;
069    import org.jfree.util.Configuration;
070    import org.jfree.util.DefaultConfiguration;
071    import org.jfree.util.StringUtils;
072    
073    /**
074     * A dialog that is used to perform the printing of a report into an HTML file.
075     */
076    public class HtmlZipExportDialog extends AbstractExportDialog
077    {
078      private static final String ZIP_FILE_EXTENSION = ".zip";
079    
080      /**
081       * An action to select the export target file.
082       */
083      private class ActionSelectTargetFile extends AbstractAction
084      {
085        /**
086         * Default constructor.
087         */
088        private ActionSelectTargetFile (final ResourceBundle resources)
089        {
090          putValue(Action.NAME, resources.getString("htmlexportdialog.select"));
091        }
092    
093        /**
094         * Receives notification that the action has occurred.
095         *
096         * @param e the action event.
097         */
098        public void actionPerformed (final ActionEvent e)
099        {
100          performSelectFile();
101        }
102    
103      }
104    
105      private JTextField filenameField;
106      private JFileChooser fileChooserHtml;
107      private JTextField dataDirField;
108      private JStatusBar statusBar;
109      private JRadioButton rbPageableExport;
110      private JRadioButton rbStreamExport;
111      private JRadioButton rbFlowExport;
112    
113    
114      /**
115       * Creates a non-modal dialog without a title and without a specified
116       * <code>Frame</code> owner.  A shared, hidden frame will be set as the owner
117       * of the dialog.
118       */
119      public HtmlZipExportDialog()
120      {
121        initializeComponents();
122      }
123    
124      /**
125       * Creates a non-modal dialog without a title with the specified
126       * <code>Frame</code> as its owner.  If <code>owner</code> is
127       * <code>null</code>, a shared, hidden frame will be set as the owner of the
128       * dialog.
129       *
130       * @param owner the <code>Frame</code> from which the dialog is displayed
131       */
132      public HtmlZipExportDialog(final Frame owner)
133      {
134        super(owner);
135        initializeComponents();
136      }
137    
138      /**
139       * Creates a non-modal dialog without a title with the specified
140       * <code>Dialog</code> as its owner.
141       *
142       * @param owner the non-null <code>Dialog</code> from which the dialog is
143       *              displayed
144       */
145      public HtmlZipExportDialog(final Dialog owner)
146      {
147        super(owner);
148        initializeComponents();
149      }
150    
151      public String getFilename()
152      {
153        return filenameField.getText();
154      }
155    
156      public void setFilename(final String filename)
157      {
158        this.filenameField.setText(filename);
159      }
160    
161      private void initializeComponents ()
162      {
163        final JPanel contentPane = new JPanel();
164        contentPane.setLayout(new GridBagLayout());
165    
166        filenameField = new JTextField();
167        dataDirField = new JTextField();
168        statusBar = new JStatusBar(new DefaultIconTheme());
169    
170        final JLabel targetLabel = new JLabel();
171        addPropertyChangeListener(new JLabelLocaleUpdateHandler(targetLabel,
172            SwingHtmlModule.BUNDLE_NAME, "htmlexportdialog.filename"));
173    
174        final JLabel dataLabel = new JLabel();
175        addPropertyChangeListener(new JLabelLocaleUpdateHandler(dataLabel,
176            SwingHtmlModule.BUNDLE_NAME, "htmlexportdialog.datafilename"));
177    
178        final JLabel exportMethodLabel =
179            new JLabel(getResources().getString("htmlexportdialog.exportMethod"));
180        addPropertyChangeListener("locale", new JLabelLocaleUpdateHandler(exportMethodLabel,
181            SwingHtmlModule.BUNDLE_NAME, "htmlexportdialog.exportMethod"));
182    
183    
184        rbStreamExport = new JRadioButton(getResources().getString
185            ("htmlexportdialog.stream-export"));
186        rbStreamExport.setSelected(true);
187        rbFlowExport = new JRadioButton(getResources().getString
188            ("htmlexportdialog.flow-export"));
189        rbPageableExport = new JRadioButton(getResources().getString
190            ("htmlexportdialog.pageable-export"));
191    
192        final ButtonGroup bgExport = new ButtonGroup();
193        bgExport.add(rbStreamExport);
194        bgExport.add(rbFlowExport);
195        bgExport.add(rbPageableExport);
196    
197        final JPanel exportTypeSelectionPanel = new JPanel();
198        exportTypeSelectionPanel.setLayout(new GridLayout(3, 1, 5, 5));
199        exportTypeSelectionPanel.add(rbStreamExport);
200        exportTypeSelectionPanel.add(rbFlowExport);
201        exportTypeSelectionPanel.add(rbPageableExport);
202    
203        GridBagConstraints gbc = new GridBagConstraints();
204        gbc.fill = GridBagConstraints.NONE;
205        gbc.anchor = GridBagConstraints.WEST;
206        gbc.gridx = 0;
207        gbc.gridy = 0;
208        gbc.insets = new Insets(1, 1, 1, 5);
209        contentPane.add(targetLabel, gbc);
210    
211        gbc = new GridBagConstraints();
212        gbc.fill = GridBagConstraints.NONE;
213        gbc.anchor = GridBagConstraints.WEST;
214        gbc.gridx = 0;
215        gbc.gridy = 1;
216        gbc.insets = new Insets(1, 1, 1, 5);
217        contentPane.add(dataLabel, gbc);
218    
219        gbc = new GridBagConstraints();
220        gbc.anchor = GridBagConstraints.WEST;
221        gbc.fill = GridBagConstraints.HORIZONTAL;
222        gbc.gridx = 1;
223        gbc.gridy = 0;
224        gbc.gridwidth = 1;
225        gbc.weightx = 1;
226        gbc.insets = new Insets(1, 1, 1, 1);
227        contentPane.add(filenameField, gbc);
228    
229        gbc = new GridBagConstraints();
230        gbc.anchor = GridBagConstraints.WEST;
231        gbc.fill = GridBagConstraints.HORIZONTAL;
232        gbc.gridx = 2;
233        gbc.gridy = 0;
234        final HtmlZipExportDialog.ActionSelectTargetFile selectTargetAction =
235            new HtmlZipExportDialog.ActionSelectTargetFile(getResources());
236        contentPane.add(new ActionButton(selectTargetAction), gbc);
237    
238        gbc = new GridBagConstraints();
239        gbc.anchor = GridBagConstraints.WEST;
240        gbc.fill = GridBagConstraints.HORIZONTAL;
241        gbc.gridx = 1;
242        gbc.gridy = 1;
243        gbc.gridwidth = 1;
244        gbc.weightx = 1;
245        gbc.insets = new Insets(1, 1, 1, 1);
246        contentPane.add(dataDirField, gbc);
247    
248    
249        gbc = new GridBagConstraints();
250        gbc.anchor = GridBagConstraints.WEST;
251        gbc.fill = GridBagConstraints.HORIZONTAL;
252        gbc.gridx = 0;
253        gbc.gridy = 2;
254        contentPane.add(exportMethodLabel, gbc);
255    
256        gbc = new GridBagConstraints();
257        gbc.anchor = GridBagConstraints.WEST;
258        gbc.fill = GridBagConstraints.HORIZONTAL;
259        gbc.gridx = 1;
260        gbc.gridy = 2;
261        gbc.gridwidth = 1;
262        gbc.insets = new Insets(1, 1, 1, 1);
263        contentPane.add(exportTypeSelectionPanel, gbc);
264    
265    
266        final JButton btnCancel = new ActionButton(getCancelAction());
267        final JButton btnConfirm = new ActionButton(getConfirmAction());
268    
269        final JPanel buttonPanel = new JPanel();
270        buttonPanel.setLayout(new GridLayout());
271        buttonPanel.add(btnConfirm);
272        buttonPanel.add(btnCancel);
273        btnConfirm.setDefaultCapable(true);
274        buttonPanel.registerKeyboardAction(getConfirmAction(),
275            KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),
276            JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
277    
278        gbc = new GridBagConstraints();
279        gbc.fill = GridBagConstraints.NONE;
280        gbc.anchor = GridBagConstraints.EAST;
281        gbc.weightx = 1;
282        gbc.gridx = 0;
283        gbc.gridwidth = 3;
284        gbc.gridy = 15;
285        gbc.insets = new Insets(10, 0, 10, 0);
286        contentPane.add(buttonPanel, gbc);
287    
288    
289        final JPanel contentWithStatus = new JPanel();
290        contentWithStatus.setLayout(new BorderLayout());
291        contentWithStatus.add(contentPane, BorderLayout.CENTER);
292        contentWithStatus.add(statusBar, BorderLayout.SOUTH);
293    
294        setContentPane(contentWithStatus);
295    
296        getFormValidator().registerTextField(dataDirField);
297        getFormValidator().registerTextField(filenameField);
298      }
299    
300    
301      public JStatusBar getStatusBar()
302      {
303        return statusBar;
304      }
305    
306      protected boolean performValidate()
307      {
308        getStatusBar().clear();
309    
310        final String filename = getFilename();
311        if (filename.trim().length() == 0)
312        {
313          getStatusBar().setStatus(JStatusBar.TYPE_ERROR,
314                  getResources().getString("htmlexportdialog.targetIsEmpty"));
315          return false;
316        }
317        final File f = new File(filename);
318        if (f.exists())
319        {
320          if (f.isFile() == false)
321          {
322            getStatusBar().setStatus(JStatusBar.TYPE_ERROR,
323                    getResources().getString("htmlexportdialog.targetIsNoFile"));
324            return false;
325          }
326          if (f.canWrite() == false)
327          {
328            getStatusBar().setStatus(JStatusBar.TYPE_ERROR,
329                    getResources().getString("htmlexportdialog.targetIsNotWritable"));
330            return false;
331          }
332    
333          final String message = MessageFormat.format(getResources().getString
334                  ("htmlexportdialog.targetExistsWarning"),
335                  new Object[]{filename});
336          getStatusBar().setStatus(JStatusBar.TYPE_WARNING, message);
337        }
338    
339        try
340        {
341          final File dataDir = new File(dataDirField.getText());
342          final File baseDir = new File("");
343    
344          if (IOUtils.getInstance().isSubDirectory(baseDir, dataDir) == false)
345          {
346            getStatusBar().setStatus(JStatusBar.TYPE_ERROR,
347                    getResources().getString("htmlexportdialog.targetPathIsAbsolute"));
348            return false;
349          }
350        }
351        catch (Exception e)
352        {
353          getStatusBar().setStatus(JStatusBar.TYPE_ERROR, "error.validationfailed");
354          return false;
355        }
356    
357        return true;
358      }
359    
360      protected boolean performConfirm()
361      {
362        final String filename = getFilename();
363        final File f = new File(filename).getAbsoluteFile();
364        if (f.exists())
365        {
366          final String key1 = "htmlexportdialog.targetOverwriteConfirmation";
367          final String key2 = "htmlexportdialog.targetOverwriteTitle";
368          if (JOptionPane.showConfirmDialog(this,
369                  MessageFormat.format(getResources().getString(key1),
370                          new Object[]{getFilename()}),
371                  getResources().getString(key2),
372                  JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE)
373                  == JOptionPane.NO_OPTION)
374          {
375            return false;
376          }
377        }
378    
379        return true;
380      }
381    
382      protected void initializeFromJob(final ReportJob job, final GuiContext guiContext)
383      {
384        statusBar.setIconTheme(guiContext.getIconTheme());
385      }
386    
387      protected String getConfigurationPrefix()
388      {
389        return "org.jfree.report.modules.gui.common.html.zip.";
390      }
391    
392      protected Configuration grabDialogContents(final boolean full)
393      {
394        final ModifiableConfiguration conf = new DefaultConfiguration();
395        if (full)
396        {
397          conf.setConfigProperty
398              ("org.jfree.report.modules.gui.common.html.zip.TargetFileName", filenameField.getText());
399          conf.setConfigProperty
400              ("org.jfree.report.modules.gui.common.html.zip.DataDirectory", dataDirField.getText());
401        }
402        conf.setConfigProperty
403            ("org.jfree.report.modules.gui.common.html.zip.ExportMethod", getExportMethod());
404    
405        return conf;
406      }
407    
408      protected void setDialogContents(final Configuration properties)
409      {
410        filenameField.setText(properties.getConfigProperty
411            ("org.jfree.report.modules.gui.common.html.zip.TargetFileName", ""));
412        dataDirField.setText(properties.getConfigProperty
413            ("org.jfree.report.modules.gui.common.html.zip.DataDirectory", ""));
414        setExportMethod(properties.getConfigProperty
415            ("org.jfree.report.modules.gui.common.html.zip.ExportMethod", ""));
416      }
417    
418    
419      protected String getConfigurationSuffix ()
420      {
421        return "_htmlexport_file";
422      }
423    
424      public String getExportMethod()
425      {
426        if (rbPageableExport.isSelected())
427        {
428          return "pageable";
429        }
430        if (rbFlowExport.isSelected())
431        {
432          return "flow";
433        }
434        return "stream";
435      }
436    
437      public void setExportMethod (final String method)
438      {
439        if ("pageable".equals(method))
440        {
441          rbPageableExport.setSelected(true);
442        }
443        else if ("flow".equals(method))
444        {
445          rbFlowExport.setSelected(true);
446        }
447        else
448        {
449          rbStreamExport.setSelected(true);
450        }
451      }
452    
453      public void clear()
454      {
455        filenameField.setText("");
456        dataDirField.setText("");
457        rbStreamExport.setSelected(true);
458      }
459    
460      protected String getResourceBaseName()
461      {
462        return SwingHtmlModule.BUNDLE_NAME;
463      }
464    
465      /**
466       * Selects a file to use as target for the report processing.
467       */
468      protected void performSelectFile ()
469      {
470        final File file = new File(getFilename());
471    
472        if (fileChooserHtml == null)
473        {
474          fileChooserHtml = new JFileChooser();
475          fileChooserHtml.addChoosableFileFilter
476                  (new FilesystemFilter(new String[]{HtmlZipExportDialog.ZIP_FILE_EXTENSION},
477                          getResources().getString("htmlexportdialog.zip-archives"), true));
478          fileChooserHtml.setMultiSelectionEnabled(false);
479        }
480    
481        fileChooserHtml.setCurrentDirectory(file);
482        fileChooserHtml.setSelectedFile(file);
483        final int option = fileChooserHtml.showSaveDialog(this);
484        if (option == JFileChooser.APPROVE_OPTION)
485        {
486          final File selFile = fileChooserHtml.getSelectedFile();
487          String selFileName = selFile.getAbsolutePath();
488    
489          // Test if ends on html
490          if (StringUtils.endsWithIgnoreCase(selFileName, HtmlZipExportDialog.ZIP_FILE_EXTENSION) == false)
491          {
492            selFileName = selFileName + HtmlZipExportDialog.ZIP_FILE_EXTENSION;
493          }
494          setFilename(selFileName);
495        }
496      }
497    
498    }