Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.datacleaner.windows.HdfsUrlChooser Maven / Gradle / Ivy
/**
* DataCleaner (community edition)
* Copyright (C) 2014 Free Software Foundation, Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.datacleaner.windows;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.HeadlessException;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import javax.swing.AbstractListModel;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import javax.ws.rs.core.UriBuilder;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.datacleaner.bootstrap.DCWindowContext;
import org.datacleaner.bootstrap.WindowContext;
import org.datacleaner.configuration.ServerInformation;
import org.datacleaner.configuration.ServerInformationCatalog;
import org.datacleaner.configuration.ServerInformationCatalogImpl;
import org.datacleaner.panels.DCPanel;
import org.datacleaner.server.DirectConnectionHadoopClusterInformation;
import org.datacleaner.server.DirectoryBasedHadoopClusterInformation;
import org.datacleaner.server.EnvironmentBasedHadoopClusterInformation;
import org.datacleaner.server.HadoopClusterInformation;
import org.datacleaner.util.HadoopResource;
import org.datacleaner.util.HdfsUtils;
import org.datacleaner.util.LookAndFeelManager;
import org.datacleaner.util.WidgetFactory;
import org.datacleaner.util.WidgetUtils;
import org.datacleaner.widgets.DCComboBox;
import org.datacleaner.widgets.DCLabel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HdfsUrlChooser extends JComponent {
public enum OpenType {
LOAD("Open"), SAVE("Save");
private final String _title;
OpenType(final String title) {
_title = title;
}
public String getTitle() {
return _title;
}
}
static class HdfsFileListRenderer extends DefaultListCellRenderer {
private static final long serialVersionUID = 1L;
public Component getListCellRendererComponent(final JList> list, final Object value, final int index,
final boolean isSelected, final boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value == null) {
setText("");
return this;
}
final FileStatus fileStatus = (FileStatus) value;
final String name;
if (fileStatus.isDirectory()) {
setIcon(DIRECTORY_ICON);
name = fileStatus.getPath().getName();
} else if (fileStatus.isFile()) {
setIcon(FILE_ICON);
name = fileStatus.getPath().getName();
} else {
name = "..";
setIcon(LEVEL_UP_ICON);
}
setText(name);
return this;
}
}
static class IndentIcon implements Icon {
Icon _icon = DIRECTORY_ICON;
int _depth = 0;
public void paintIcon(final Component c, final Graphics graphics, final int x, final int y) {
if (c.getComponentOrientation().isLeftToRight()) {
_icon.paintIcon(c, graphics, x + _depth * SPACE, y);
} else {
_icon.paintIcon(c, graphics, x, y);
}
}
public int getIconWidth() {
return _icon.getIconWidth() + _depth * SPACE;
}
public int getIconHeight() {
return _icon.getIconHeight();
}
}
class ServerComboBoxRenderer extends DefaultListCellRenderer {
private static final long serialVersionUID = 1L;
IndentIcon ii = new IndentIcon();
public Component getListCellRendererComponent(final JList> list, final Object value, final int index,
final boolean isSelected, final boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value == null) {
setText("");
return this;
}
final Path directory = (Path) value;
final String directoryName = directory.getName();
if (directoryName.isEmpty()) {
final URI uri = directory.toUri();
setText(uri.toString());
} else {
setText(directoryName);
}
final int depth = _directoryComboBoxModel.getDepth(index);
ii._depth = depth;
if (depth == 0) {
ii._icon = COMPUTER_ICON;
}
setIcon(ii);
return this;
}
}
class HdfsComboBoxModel extends AbstractListModel implements ComboBoxModel {
private static final long serialVersionUID = 1L;
LinkedList directories = new LinkedList<>();
int[] depths = null;
Path selectedDirectory = null;
public HdfsComboBoxModel() {
updateDirectories();
}
public void updateDirectories() {
final Path dir = getCurrentDirectory();
if (dir != null) {
addItem(dir);
}
}
private void addItem(final Path directory) {
if (directory == null) {
return;
}
directories.clear();
directories.add(getRoot());
Path path = directory;
final List paths = new ArrayList<>(10);
do {
paths.add(path);
} while ((path = path.getParent()) != null);
final int pathCount = paths.size();
for (int i = 0; i < pathCount; i++) {
path = paths.get(i);
if (directories.contains(path)) {
final int topIndex = directories.indexOf(path);
for (int j = i - 1; j >= 0; j--) {
directories.add(topIndex + i - j, paths.get(j));
}
break;
}
}
calculateDepths();
setSelectedItem(directory);
}
private void calculateDepths() {
depths = new int[directories.size()];
for (int i = 0; i < depths.length; i++) {
final Path dir = directories.get(i);
final Path parent = dir.getParent();
depths[i] = 0;
if (parent != null) {
for (int j = i - 1; j >= 0; j--) {
if (parent.equals(directories.get(j))) {
depths[i] = depths[j] + 1;
break;
}
}
}
}
}
public int getDepth(final int index) {
if (depths == null || index < 0 || index > depths.length) {
return 0;
}
return depths[index];
}
@Override
public Path getSelectedItem() {
return selectedDirectory;
}
@Override
public void setSelectedItem(final Object selectedDirectory) {
this.selectedDirectory = (Path) selectedDirectory;
fireContentsChanged(this, -1, -1);
}
@Override
public int getSize() {
return directories.size();
}
@Override
public Path getElementAt(final int index) {
return directories.get(index);
}
}
public class HdfsDirectoryModel extends AbstractListModel implements PropertyChangeListener {
private static final long serialVersionUID = 1L;
private FileStatus[] _files;
public HdfsDirectoryModel() {
updateFileList();
}
private void updateFileList() {
if (_fileSystem == null || _currentDirectory == null) {
_files = new FileStatus[0];
return;
}
FileStatus[] fileStatuses;
try {
fileStatuses = _fileSystem.listStatus(_currentDirectory);
// Natural ordering is the URL
Arrays.sort(fileStatuses);
// Add pointer to the parent directory
if (!_currentDirectory.isRoot()) {
final FileStatus[] newFileStatuses = new FileStatus[fileStatuses.length + 1];
final FileStatus levelUp = new FileStatus();
levelUp.setSymlink(_currentDirectory.getParent());
newFileStatuses[0] = levelUp;
System.arraycopy(fileStatuses, 0, newFileStatuses, 1, fileStatuses.length);
fileStatuses = newFileStatuses;
}
} catch (final IOException e) {
fileStatuses = new FileStatus[0];
}
synchronized (this) {
_files = fileStatuses;
fireContentsChanged(this, 0, getSize() - 1);
}
}
@Override
public int getSize() {
synchronized (this) {
return _files.length;
}
}
@Override
public FileStatus getElementAt(final int index) {
synchronized (this) {
return _files[index];
}
}
@Override
public void propertyChange(final PropertyChangeEvent evt) {
updateFileList();
}
}
public static final Icon DIRECTORY_ICON = UIManager.getIcon("FileView.directoryIcon");
public static final Icon FILE_ICON = UIManager.getIcon("FileView.fileIcon");
public static final Icon COMPUTER_ICON = UIManager.getIcon("FileView.computerIcon");
public static final Icon LEVEL_UP_ICON = UIManager.getLookAndFeelDefaults().getIcon("FileChooser.upFolderIcon");
protected static final Logger logger = LoggerFactory.getLogger(HdfsUrlChooser.class);
private static final long serialVersionUID = 1L;
private static final int DEFAULT_WIDTH = 600;
private static final int SPACE = 10;
public static String HDFS_SCHEME = "hdfs";
private final OpenType _openType;
private final JList _fileList;
private FileSystem _fileSystem;
private JDialog _dialog = null;
private Path _currentDirectory;
private Path _selectedFile;
private HdfsComboBoxModel _directoryComboBoxModel = new HdfsComboBoxModel();
HdfsUrlChooser(URI uri, final OpenType openType) {
if (uri != null) {
if (!HDFS_SCHEME.equals(uri.getScheme())) {
throw new IllegalArgumentException("Only HDFS allowed");
}
uri = UriBuilder.fromUri(uri).replaceQuery(null).fragment(null).build();
HdfsUtils.getFileSystemFromUri(uri);
_currentDirectory = new Path(uri);
}
_openType = openType;
final DCLabel lookInLabel = DCLabel.dark("Look in:");
final DCComboBox pathsComboBox = new DCComboBox<>(_directoryComboBoxModel);
pathsComboBox.setRenderer(new ServerComboBoxRenderer());
pathsComboBox.setMinimumSize(new Dimension(DEFAULT_WIDTH, 40));
pathsComboBox.addListener(new DCComboBox.Listener() {
@Override
public void onItemSelected(final Path directory) {
if (!directory.isAbsoluteAndSchemeAuthorityNull()) {
_fileSystem = HdfsUtils.getFileSystemFromUri(directory.toUri());
}
_currentDirectory = directory;
((HdfsDirectoryModel) _fileList.getModel()).updateFileList();
}
});
_fileList = new JList<>(new HdfsDirectoryModel());
_fileList.setLayoutOrientation(JList.VERTICAL_WRAP);
_fileList.setPreferredSize(new Dimension(DEFAULT_WIDTH, 350));
_fileList.setBorder(WidgetUtils.BORDER_THIN);
_fileList.setCellRenderer(new HdfsFileListRenderer());
_fileList.addMouseListener(new MouseAdapter() {
public void mouseClicked(final MouseEvent evt) {
if (evt.getClickCount() == 2) {
selectOrBrowsePath(false);
}
}
@Override
public void mousePressed(final MouseEvent e) {
tryPopup(e);
}
@Override
public void mouseReleased(final MouseEvent e) {
tryPopup(e);
}
private void tryPopup(final MouseEvent e) {
if (e.isPopupTrigger()) {
_fileList.setSelectedIndex(_fileList.locationToIndex(e.getPoint()));
final JPopupMenu popupMenu = new JPopupMenu();
if (_fileList.getModel().getElementAt(_fileList.getSelectedIndex()).isDirectory()) {
final JMenuItem browseMenuItem = new JMenuItem("Browse");
browseMenuItem.addActionListener(e1 -> selectOrBrowsePath(false));
popupMenu.add(browseMenuItem);
}
final JMenuItem selectMenuItem = new JMenuItem("Select");
selectMenuItem.addActionListener(e1 -> selectOrBrowsePath(true));
popupMenu.add(selectMenuItem);
popupMenu.show(_fileList, e.getX(), e.getY());
}
}
});
setLayout(new BorderLayout());
final DCPanel topPanel = new DCPanel();
topPanel.setLayout(new GridBagLayout());
topPanel.setPreferredSize(new Dimension(DEFAULT_WIDTH, 40));
WidgetUtils.addToGridBag(lookInLabel, topPanel, 0, 0, 1, 1, GridBagConstraints.WEST, 5);
WidgetUtils.addToGridBag(pathsComboBox, topPanel, 1, 0, 100, 40, GridBagConstraints.WEST, 5, 1, 1,
GridBagConstraints.HORIZONTAL);
add(topPanel, BorderLayout.NORTH);
final DCPanel panel = DCPanel.around(_fileList);
panel.setBorder(WidgetUtils.BORDER_EMPTY);
add(panel, BorderLayout.CENTER);
}
public static URI showDialog(final Component parent, final ServerInformationCatalog serverInformationCatalog,
final String selectedServer, final URI currentUri, final OpenType openType) throws HeadlessException {
final HdfsUrlChooser chooser = new HdfsUrlChooser(currentUri, openType);
if (chooser._dialog != null) {
// Prevent to show second instance of _dialog if the previous one
// still exists
return null;
}
final ComponentListener listener = new ComponentAdapter() {
@Override
public void componentShown(final ComponentEvent e) {
if (chooser._currentDirectory == null) {
final boolean configured = chooser.scanHadoopConfigFiles(serverInformationCatalog, selectedServer);
if (configured) {
chooser.updateDirectories();
} else {
final URI uri = HdfsServerAddressDialog.showHdfsNameNodeDialog(chooser, chooser.getUri());
if (uri != null) {
chooser.updateCurrentDirectory(new Path(uri));
} else {
chooser.updateCurrentDirectory(null);
chooser._dialog.setVisible(false);
}
}
}
}
};
chooser.createDialog(chooser, parent, listener);
if (chooser.getUri() != null) {
chooser.rescanServer();
}
final Path selectedFile = chooser.getSelectedFile();
if (selectedFile != null) {
return selectedFile.toUri();
}
return null;
}
private void selectOrBrowsePath(final boolean selectDirectory) {
// Double-click detected
final FileStatus element = _fileList.getModel().getElementAt(_fileList.getSelectedIndex());
if (element.isSymlink()) {
try {
_currentDirectory = element.getSymlink();
} catch (final IOException e) {
logger.warn("Could not get the symlink value for element {}", element, e);
}
} else if (element.isFile() || (element.isDirectory() && selectDirectory)) {
_selectedFile = element.getPath();
logger.info("Selected: " + _selectedFile);
_dialog.dispose();
} else if (element.isDirectory()) {
_currentDirectory = element.getPath();
_directoryComboBoxModel.updateDirectories();
}
((HdfsDirectoryModel) _fileList.getModel()).updateFileList();
}
/**
* This scans Hadoop environment variables for a directory with configuration files
*
* @param serverInformationCatalog
* @return True if a configuration was yielded.
*/
private boolean scanHadoopConfigFiles(final ServerInformationCatalog serverInformationCatalog,
final String selectedServer) {
final HadoopClusterInformation clusterInformation;
if (selectedServer != null) {
clusterInformation = (HadoopClusterInformation) serverInformationCatalog.getServer(selectedServer);
} else {
clusterInformation = (HadoopClusterInformation) serverInformationCatalog
.getServer(HadoopResource.DEFAULT_CLUSTERREFERENCE);
}
if (clusterInformation == null) {
return false;
}
final Configuration configuration = HdfsUtils.getHadoopConfigurationWithTimeout(clusterInformation);
_currentDirectory = new Path("/");
try {
_fileSystem = FileSystem.newInstance(configuration);
} catch (final IOException e) {
throw new IllegalArgumentException("Illegal URI when showing HDFS chooser", e);
}
final HdfsDirectoryModel model = (HdfsDirectoryModel) _fileList.getModel();
model.updateFileList();
return model._files.length > 0;
}
private void updateDirectories() {
_directoryComboBoxModel.updateDirectories();
}
private void updateCurrentDirectory(final Path directory) {
_currentDirectory = directory;
if (directory != null) {
_fileSystem = HdfsUtils.getFileSystemFromUri(directory.toUri());
((HdfsDirectoryModel) _fileList.getModel()).updateFileList();
updateDirectories();
}
}
private Path getCurrentDirectory() {
return _currentDirectory;
}
private Path getRoot() {
Path path = getCurrentDirectory();
while (!path.isRoot()) {
path = path.getParent();
}
return path;
}
private void rescanServer() {
if (_fileSystem != null && getUri() != null) {
try {
_fileSystem.listStatus(new Path(getUri()));
} catch (final IOException e) {
throw new RuntimeException(e);
}
}
}
protected void createDialog(final Component chooser, final Component parent, final ComponentListener listener) {
_dialog = WidgetFactory.createModalDialog(chooser, parent, _openType.getTitle(), true);
if (listener != null) {
_dialog.addComponentListener(listener);
}
_dialog.setVisible(true);
_dialog.dispose();
_dialog = null;
}
public URI getUri() {
return _currentDirectory == null ? null : _currentDirectory.toUri();
}
private Path getSelectedFile() {
return _selectedFile;
}
// Test
public static void main(final String[] args) throws URISyntaxException {
LookAndFeelManager.get().init();
final List servers = new ArrayList<>();
servers.add(new EnvironmentBasedHadoopClusterInformation("default", "hadoop conf dir"));
servers.add(new DirectoryBasedHadoopClusterInformation("directory", "directopry set up",
"C:\\Users\\claudiap\\git\\vagrant-vms\\bigdatavm\\hadoop_conf"));
servers.add(new DirectConnectionHadoopClusterInformation("namenode", "directconnection",
new URI("hdfs://192.168.0.255:9000/")));
final ServerInformationCatalog serverInformationCatalog = new ServerInformationCatalogImpl(servers);
final JFrame frame = new JFrame("test");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setSize(DEFAULT_WIDTH, 400);
frame.pack();
frame.setVisible(true);
final WindowContext windowContext = new DCWindowContext(null, null);
final SelectHadoopClusterDialog selectHadoopConfigurationDialog =
new SelectHadoopClusterDialog(windowContext, serverInformationCatalog, null);
selectHadoopConfigurationDialog.setVisible(true);
final String selectedServer = selectHadoopConfigurationDialog.getSelectedConfiguration();
try {
final URI selectedFile =
HdfsUrlChooser.showDialog(frame, serverInformationCatalog, selectedServer, null, OpenType.LOAD);
System.out.println("Normal exit, selected file: " + selectedFile);
System.exit(0);
} catch (final Exception e) {
System.err.println("Abnormal exit");
e.printStackTrace(System.err);
System.exit(1);
}
}
}