Java tutorial
/*! * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * Copyright (c) 2002-2017 Hitachi Vantara.. All rights reserved. */ package org.pentaho.reporting.designer.extensions.pentaho.repository.dialogs; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.vfs2.FileName; import org.apache.commons.vfs2.FileObject; import org.apache.commons.vfs2.FileSystemException; import org.apache.commons.vfs2.FileType; import org.apache.commons.vfs2.VFS; import org.pentaho.reporting.designer.core.auth.AuthenticationData; import org.pentaho.reporting.designer.core.util.exceptions.UncaughtExceptionsModel; import org.pentaho.reporting.designer.extensions.pentaho.repository.Messages; import org.pentaho.reporting.designer.extensions.pentaho.repository.util.PublishUtil; import org.pentaho.reporting.libraries.base.util.DebugLog; import org.pentaho.reporting.libraries.base.util.IOUtils; import org.pentaho.reporting.libraries.base.util.StringUtils; import org.pentaho.reporting.libraries.designtime.swing.BorderlessButton; import org.pentaho.reporting.libraries.designtime.swing.CommonDialog; import org.pentaho.reporting.libraries.designtime.swing.event.DocumentChangeHandler; import org.pentaho.reporting.libraries.pensol.WebSolutionFileObject; import org.pentaho.reporting.libraries.pensol.vfs.WebSolutionFileSystem; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.ComboBoxModel; import javax.swing.DefaultComboBoxModel; import javax.swing.DefaultListCellRenderer; import javax.swing.ImageIcon; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.border.EmptyBorder; import javax.swing.event.DocumentEvent; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dialog; import java.awt.Frame; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URL; import java.net.URLDecoder; import java.util.ArrayList; public class RepositoryOpenDialog extends CommonDialog { protected class LevelUpAction extends AbstractAction { /** * Defines an <code>Action</code> object with a default description string and default icon. */ public LevelUpAction() { putValue(Action.SHORT_DESCRIPTION, Messages.getInstance().getString("RepositoryPublishDialog.LevelUpAction.Description")); final URL location = RepositoryOpenDialog.class.getResource( "/org/pentaho/reporting/designer/extensions/pentaho/repository/resources/upOneFolder.png"); // NON-NLS if (location != null) { putValue(Action.SMALL_ICON, new ImageIcon(location)); } else { putValue(Action.NAME, Messages.getInstance().getString("RepositoryPublishDialog.LevelUpAction.Name")); } } /** * Invoked when an action occurs. */ public void actionPerformed(final ActionEvent e) { if (fileSystemRoot == null) { return; } if (fileSystemRoot.equals(selectedView)) { return; } try { setSelectedView(selectedView.getParent()); } catch (FileSystemException e1) { UncaughtExceptionsModel.getInstance().addException(e1); } } } protected class BrowseRepositoryAction extends AbstractAction { /** * Defines an <code>Action</code> object with a default description string and default icon. */ public BrowseRepositoryAction() { putValue(Action.SHORT_DESCRIPTION, Messages.getInstance().getString("RepositoryPublishDialog.BrowseRepositoryAction.Description")); final URL location = RepositoryOpenDialog.class.getResource( "/org/pentaho/reporting/designer/extensions/pentaho/repository/resources/exploreSolution.png"); // NON-NLS if (location != null) { putValue(Action.SMALL_ICON, new ImageIcon(location)); } else { putValue(Action.NAME, Messages.getInstance().getString("RepositoryPublishDialog.BrowseRepositoryAction.Name")); } } /** * Invoked when an action occurs. */ public void actionPerformed(final ActionEvent e) { if (fileSystemRoot == null) { return; } final RepositoryTreeDialog treeDialog = new RepositoryTreeDialog(RepositoryOpenDialog.this, isCreateFolderAllowed()); try { final FileObject newLocation = treeDialog.performSelectLocation(fileSystemRoot, getFilters(), selectedView); if (newLocation != null) { setSelectedView(newLocation); } if (treeDialog.isDirty()) { table.refresh(); } } catch (FileSystemException e1) { UncaughtExceptionsModel.getInstance().addException(e1); } } } private class TableInputHandler extends MouseAdapter implements KeyListener, ListSelectionListener { private TableInputHandler() { } /** * Invoked when a key has been typed. See the class description for {@link java.awt.event.KeyEvent} for a definition * of a key typed event. */ public void keyTyped(final KeyEvent e) { } /** * Invoked when a key has been pressed. See the class description for {@link java.awt.event.KeyEvent} for a * definition of a key pressed event. */ public void keyPressed(final KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ENTER) { final int selectedRowRaw = table.getSelectedRow(); if (selectedRowRaw == -1) { return; } final int selectedRow = table.convertRowIndexToModel(selectedRowRaw); final FileObject selectedFileObject = table.getSelectedFileObject(selectedRow); if (selectedFileObject == null) { return; } try { if (FileType.FOLDER.equals(selectedFileObject.getType())) { setSelectedView(selectedFileObject); } } catch (FileSystemException e1) { // ignore .. } } } /** * Invoked when a key has been released. See the class description for {@link java.awt.event.KeyEvent} for a * definition of a key released event. */ public void keyReleased(final KeyEvent e) { } /** * {@inheritDoc} */ public void mouseClicked(final MouseEvent e) { if (e.getButton() != 1) { return; } if (e.getClickCount() < 2) { return; } final int selectedRowRaw = table.getSelectedRow(); if (selectedRowRaw == -1) { return; } final int selectedRow = table.convertRowIndexToModel(selectedRowRaw); final FileObject selectedFileObject = table.getSelectedFileObject(selectedRow); if (selectedFileObject == null) { return; } try { if (FileType.FOLDER.equals(selectedFileObject.getType())) { setSelectedView(selectedFileObject); } else if (FileType.FILE.equals(selectedFileObject.getType())) { if (isDoubleClickConfirmsDialog() == false) { return; } setConfirmed(true); setVisible(false); } } catch (FileSystemException e1) { // ignore .. } } /** * Called whenever the value of the selection changes. * * @param e * the event that characterizes the change. */ public void valueChanged(final ListSelectionEvent e) { final int selectedRowRaw = table.getSelectedRow(); if (selectedRowRaw == -1) { return; } final int selectedRow = table.convertRowIndexToModel(selectedRowRaw); final FileObject selectedFileObject = table.getSelectedFileObject(selectedRow); if (selectedFileObject == null) { return; } try { if (selectedFileObject.getType() == FileType.FILE) { fileNameTextField.setText(URLDecoder .decode(selectedFileObject.getName().getBaseName().replaceAll("\\+", "%2B"), "UTF-8")); } } catch (FileSystemException e1) { // ignore .. } catch (UnsupportedEncodingException e1) { // ignore .. } } } private static class FileObjectRenderer extends DefaultListCellRenderer { private FileObjectRenderer() { } public Component getListCellRendererComponent(final JList list, final Object value, final int index, final boolean isSelected, final boolean cellHasFocus) { if (value instanceof WebSolutionFileObject) { final WebSolutionFileObject fo = (WebSolutionFileObject) value; final FileName fileName = fo.getName(); try { return super.getListCellRendererComponent(list, fileName.getPathDecoded(), index, isSelected, cellHasFocus); } catch (FileSystemException e) { // ignored .. } } return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); } } private class FileNameValidator extends DocumentChangeHandler { private FileNameValidator() { } protected void handleChange(final DocumentEvent e) { getConfirmAction().setEnabled(validateInputs(false)); } } private class SelectLocationAction implements ActionListener { private SelectLocationAction() { } /** * Invoked when an action occurs. */ public void actionPerformed(final ActionEvent e) { if (locationCombo.getSelectedItem() instanceof FileObject) { final FileObject selectedItem = (FileObject) locationCombo.getSelectedItem(); if (selectedItem.equals(getSelectedView()) == false) { setSelectedView(selectedItem); } } } } private class ShowHiddenFilesAction extends AbstractAction { private ShowHiddenFilesAction() { putValue(Action.NAME, Messages.getInstance().getString("ShowHiddenFilesAction.Name")); setSelected(Boolean.FALSE); } private Boolean getSelected() { return (Boolean) this.getValue(Action.SELECTED_KEY); } private void setSelected(final Boolean selected) { this.putValue(Action.SELECTED_KEY, selected); } /** * Invoked when an action occurs. */ public void actionPerformed(final ActionEvent e) { table.setShowHiddenFiles(Boolean.TRUE.equals(getSelected())); } } private static final String[] REPORT_FILTER = new String[] { ".prpt", ".report", ".prpti" }; private static final Log logger = LogFactory.getLog(RepositoryOpenDialog.class); private RepositoryTable table; private JTextField fileNameTextField; private JComboBox locationCombo; private FileObject fileSystemRoot; private FileObject selectedView; public RepositoryOpenDialog() { init(); } public RepositoryOpenDialog(final Frame owner) { super(owner); init(); } public RepositoryOpenDialog(final Dialog owner) { super(owner); init(); } public void init() { locationCombo = new JComboBox(); locationCombo.setRenderer(new FileObjectRenderer()); locationCombo.addActionListener(new SelectLocationAction()); fileNameTextField = new JTextField(); fileNameTextField.getDocument().addDocumentListener(new FileNameValidator()); table = new RepositoryTable(); table.setFilters(REPORT_FILTER); table.addKeyListener(new TableInputHandler()); table.addMouseListener(new TableInputHandler()); table.getSelectionModel().addListSelectionListener(new TableInputHandler()); super.init(); } protected String getDialogId() { return "ReportDesigner.Pentaho.RepositoryOpen"; } public String[] getFilters() { return table.getFilters(); } public void setFilters(final String[] filters) { table.setFilters(filters); } protected FileObject getSelectedView() { return selectedView; } public void setSelectedView(final FileObject selectedView) { this.selectedView = selectedView; if (selectedView != null) { logger.debug("Setting selected view to " + selectedView); try { if (selectedView.getType() == FileType.FILE) { logger.debug("Setting filename in selected view to " + selectedView.getName().getBaseName()); this.fileNameTextField .setText(URLDecoder.decode(selectedView.getName().getBaseName(), "UTF-8")); } } catch (Exception e) { // can be ignored .. logger.debug("Unable to determine file type. This is not fatal.", e); } final ComboBoxModel comboBoxModel = createLocationModel(selectedView); this.locationCombo.setModel(comboBoxModel); this.table.setSelectedPath((FileObject) comboBoxModel.getSelectedItem()); } else { this.fileNameTextField.setText(null); this.table.setSelectedPath(null); this.locationCombo.setModel(new DefaultComboBoxModel()); } } private ComboBoxModel createLocationModel(final FileObject selectedFolder) { if (fileSystemRoot == null) { return new DefaultComboBoxModel(); } try { final ArrayList<FileObject> list = new ArrayList<FileObject>(); FileObject folder = selectedFolder; while (folder != null) { if (fileSystemRoot.equals(folder)) { break; } if (folder.getType() != FileType.FILE) { list.add(folder); } final FileObject parent = folder.getParent(); if (folder.equals(parent)) { // protect yourself against infinite loops .. break; } folder = parent; } list.add(fileSystemRoot); final DefaultComboBoxModel model = new DefaultComboBoxModel(list.toArray()); model.setSelectedItem(list.get(0)); return model; } catch (FileSystemException e) { return new DefaultComboBoxModel(); } } public String performOpen(final AuthenticationData loginData, final String previousSelection) throws FileSystemException, UnsupportedEncodingException { fileSystemRoot = PublishUtil.createVFSConnection(VFS.getManager(), loginData); if (previousSelection == null) { setSelectedView(fileSystemRoot); } else { final FileObject view = fileSystemRoot.resolveFile(previousSelection); if (view == null) { setSelectedView(fileSystemRoot); } else { if (view.exists() == false) { setSelectedView(fileSystemRoot); } else if (view.getType() == FileType.FOLDER) { setSelectedView(view); } else { setSelectedView(view.getParent()); } } } if (StringUtils.isEmpty(fileNameTextField.getText(), true) && previousSelection != null) { final String fileName = IOUtils.getInstance().getFileName(previousSelection); DebugLog.log("Setting filename to " + fileName); fileNameTextField.setText(fileName); } getConfirmAction().setEnabled(validateInputs(false)); if (super.performEdit() == false || selectedView == null) { return null; } return getSelectedFile(); } protected String getSelectedFile() throws FileSystemException, UnsupportedEncodingException { if (StringUtils.isEmpty(fileNameTextField.getText())) { return null; } if (selectedView.getType() == FileType.FILE) { selectedView = selectedView.getParent(); } final FileObject targetFile = selectedView.resolveFile(fileNameTextField.getText().replaceAll("\\%", "%25") .replaceAll("\\!", "%21").replaceAll(":", "%3A")); return targetFile.getName().getPathDecoded(); } protected RepositoryTable getTable() { return table; } protected JTextField getFileNameTextField() { return fileNameTextField; } protected JComboBox getLocationCombo() { return locationCombo; } protected Component createContentPane() { final JPanel centerCarrier = new JPanel(); centerCarrier.setLayout(new BorderLayout()); centerCarrier.setBorder(new EmptyBorder(5, 5, 5, 5)); centerCarrier.add(new JScrollPane(table), BorderLayout.CENTER); centerCarrier.add(new JCheckBox(new ShowHiddenFilesAction()), BorderLayout.SOUTH); final JPanel contentPanel = new JPanel(); contentPanel.setLayout(new BorderLayout()); contentPanel.add(centerCarrier, BorderLayout.CENTER); contentPanel.add(createHeaderPanel(), BorderLayout.NORTH); return contentPanel; } protected boolean isCreateFolderAllowed() { return false; } protected boolean isDoubleClickConfirmsDialog() { return true; } protected JPanel createHeaderPanel() { final JPanel publishHeaderPanel = new JPanel(new GridBagLayout()); final GridBagConstraints c = new GridBagConstraints(); c.gridx = 0; c.gridy = 0; c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(5, 5, 5, 5); publishHeaderPanel.add(new JLabel(Messages.getInstance().getString("RepositoryPublishDialog.ReportName")), c); c.gridy = 1; c.insets = new Insets(2, 5, 0, 5); publishHeaderPanel.add(fileNameTextField, c); c.gridy = 4; c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(2, 5, 0, 5); publishHeaderPanel.add(new JLabel(Messages.getInstance().getString("RepositoryPublishDialog.Location")), c); c.insets = new Insets(0, 0, 0, 0); c.gridx = 0; c.gridy = 5; c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 1.0; c.anchor = GridBagConstraints.WEST; publishHeaderPanel.add(createLocationFieldPanel(), c); return publishHeaderPanel; } protected JPanel createLocationFieldPanel() { final GridBagConstraints c = new GridBagConstraints(); final JPanel locationFieldPanel = new JPanel(); locationFieldPanel.setLayout(new GridBagLayout()); c.insets = new Insets(0, 5, 5, 0); c.gridx = 0; c.gridy = 0; c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 1.0; c.anchor = GridBagConstraints.WEST; locationFieldPanel.add(locationCombo, c); c.insets = new Insets(5, 8, 5, 0); c.gridx = 1; c.gridy = 0; c.fill = GridBagConstraints.NONE; c.weightx = 0.0; c.anchor = GridBagConstraints.WEST; locationFieldPanel.add(new BorderlessButton(new LevelUpAction()), c); c.gridx = 2; c.gridy = 0; c.fill = GridBagConstraints.NONE; c.weightx = 0.0; c.anchor = GridBagConstraints.EAST; locationFieldPanel.add(new BorderlessButton(new BrowseRepositoryAction()), c); return locationFieldPanel; } protected boolean validateInputs(final boolean onConfirm) { if (StringUtils.isEmpty(fileNameTextField.getText())) { return false; } return true; } public void refresh() throws IOException { final WebSolutionFileSystem fileSystem = (WebSolutionFileSystem) this.fileSystemRoot.getFileSystem(); fileSystem.getLocalFileModel().refresh(); table.refresh(); } }