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,v 1.6 2007/04/01 18:49:31 taqua Exp $
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 public 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(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(boolean full)
393 {
394 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(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 (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 }