本节,简单介绍HDFS文件系统浏览器的文件系统对象。文件系统对象和HDFS文件系统对象一致,分为目录和文件,文件不再进行具体的区分文件类型。文件系统对象在UI上表现为文件系统树上的节点。FileSystemObject整个设计的类图如下:
文件系统对象的接口定义 FileSystemObject
文件系统对象在UI上表现为树节点,因此该接口需要继承自定义的树节点接口FileSystemBrowserTreeNode接口。FileSystemObject接口定义了文件系统对象的相关属性和方法,包括显示的名称、图标、对象类型(目录还是文件)、关联的连接处理对象、父对象等等。直接贴代码了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
|
public interface FileSystemObject extends FileSystemBrowserTreeNode,DynamicContentElement, Referenceable, PresentableConnectionProvider {
FileSystemObjectType getObjectType();
@NotNull String getName();
int getOverload();
String getTypeName();
@Nullable Icon getIcon();
@NotNull ConnectionHandler getConnectionHandler();
FileSystemObject getParentObject();
@NotNull FileSystemObjectBundle getObjectBundle();
@Nullable FileSystemObject getDefaultNavigationObject();
@Nullable FileSystemObject getUndisposedElement();
FileSystemObjectProperties getProperties();
List<PresentableProperty> getPresentableProperties();
FileSystemObjectRef getRef();
boolean isValid();
@NotNull FileSystemBrowserTreeNode getParent(); }
|
HDFS根目录对象FileSystemObjectBundle接口定义
我们把HDFS根目录”/“ 下的对象(目录也好文件也好)单独拿出来,定义成FileSystemObjectBundle,这样设计是为后面读取HDFS对象方便绑定到UI上进行显示,他也是TreeNode,因此也继承了FileSystemBrowserTreeNode,他只是个标志,并拥有 获取根节点对象的数据连接处理对象。代码如下:
|
public interface FileSystemObjectBundle extends FileSystemBrowserTreeNode, Disposable {
ConnectionHandler getConnectionHandler(); }
|
文件系统对象的抽象实现 FileSystemObjectImpl
抽象实现类中,有两个构造函数:
1、该构造函数以文件系统对象的父对象、HDFS的FIleStatus和对象的名称为参数
|
protected FileSystemObjectImpl(FileSystemObject parentObject, org.apache.hadoop.fs.FileStatus HDFSFileStatus, String name) { this.connectionHandlerRef = ConnectionHandlerRef.from(parentObject.getConnectionHandler()); this.parentObjectRef = FileSystemObjectRef.from(parentObject); this.name = name; init(HDFSFileStatus,null); }
|
2、该构造函数以文件系统对象连接处理对象、HDFS的FIleStatus和对象的名称为参数,当读取HDFS的根目录“/”对象的时候,调用该构造函数,除此之外,调用构造函数1
|
protected FileSystemObjectImpl(ConnectionHandler connectionHandler, org.apache.hadoop.fs.FileStatus HDFSFileStatus, String name) { this.connectionHandlerRef = ConnectionHandlerRef.from(connectionHandler); this.name = name; init(HDFSFileStatus,connectionHandler); }
|
方法 init(org.apache.hadoop.fs.FileStatus HDFSFileStatus,ConnectionHandler connectionHandler),构建对象的引用,并且读取对象的相关信息,目录或文件的创建者、文件目录大小、文件目录路径等等。
|
private void init(org.apache.hadoop.fs.FileStatus HDFSFileStatus,ConnectionHandler connectionHandler) { FileSystemObjectType fileSystemObjectType = HDFSFileStatus.isDirectory()? FileSystemObjectType.DIRECTORY: FileSystemObjectType.FILE; this.objectRef = new FileSystemObjectRef(this, fileSystemObjectType,connectionHandler); fileSystemInform = HDFSUtil.getFileSystemInformation(HDFSFileStatus); }
|
内部构建子对象
获取该对象的全部子对象,使用多线程的方式,获取其子对象,调用抽象方法(该抽象方法在具体的对象实现类中去重写) :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public abstract List<FileSystemBrowserTreeNode> buildAllPossibleTreeChildren(); public List<? extends FileSystemBrowserTreeNode> getChildren() { if (this.visibleTreeChildren == null) { synchronized (this) { if (this.visibleTreeChildren == null) { this.visibleTreeChildren = new ArrayList(); this.visibleTreeChildren.add(new LoadInProgressTreeNode(this)); ConnectionHandler connectionHandler = getConnectionHandler(); String connectionString = connectionHandler == null ? "" : " (" + connectionHandler.getName() + ")"; new BackgroundTask(getProject(), "Loading data " + connectionString, true) { public void execute(@NotNull ProgressIndicator progressIndicator) { buildTreeChildren(false); } }.start(); } } } return this.visibleTreeChildren; }
|
内部构建子对象:首先获取全部可能的对象,然后遍历对象,进行对象的初始化,判断是否是加载数据节点,是的话,删除该节点,并设置该对象的子对象加载完毕标志,最后,触发通知,TreeNode已经修改,需要重新加载该对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| private void buildTreeChildren(boolean isreBuild) { FailsafeUtil.check(this); List<FileSystemBrowserTreeNode> allPossibleTreeChildren = getAllPossibleTreeChildren(isreBuild); List<FileSystemBrowserTreeNode> newTreeChildren = allPossibleTreeChildren; if (allPossibleTreeChildren.size() > 0) { newTreeChildren = new ArrayList(newTreeChildren); for (FileSystemBrowserTreeNode treeNode : newTreeChildren) { FileSystemObject objectList = (FileSystemObject) treeNode; objectList.initTreeElement(); FailsafeUtil.check(this); } if ((this.visibleTreeChildren.size() == 1) && ((this.visibleTreeChildren.get(0) instanceof LoadInProgressTreeNode))) { this.visibleTreeChildren.get(0).dispose(); } } this.visibleTreeChildren = newTreeChildren; this.treeChildrenLoaded = true; Project project = FailsafeUtil.get(getProject()); ( EventUtil.notify(project, BrowserTreeEventListener.TOPIC)).nodeChanged(this, TreeEventType.STRUCTURE_CHANGED); FileSystemBrowserManager.scrollToSelectedElement(getConnectionHandler()); }
|
HDFS的目录和文件对象的实现 HadoopDirectoryObject 、HadoopFileObject
HDFS目录对象的实现HadoopDirectoryObject。
继承抽象类FileSystemObjectImpl和,重写对象类型、HDFS目录所在的路径、获取目录对象的子对象。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
public class HadoopDirectoryObject extends FileSystemObjectImpl { private List<FileSystemBrowserTreeNode> fileSystemBrowserTreeNodeLists =null; private org.apache.hadoop.fs.FileStatus fileStatus=null;
public HadoopDirectoryObject(FileSystemObject parentObject, org.apache.hadoop.fs.FileStatus resultSet, String name) { super(parentObject,resultSet,name); fileStatus = resultSet; }
public HadoopDirectoryObject(ConnectionHandler connectionHandler, org.apache.hadoop.fs.FileStatus resultSet, String name) { super(connectionHandler,resultSet,name); fileStatus = resultSet; fileSystemBrowserTreeNodeLists = new ArrayList(); }
public FileSystemObjectType getObjectType() { return FileSystemObjectType.DIRECTORY; }
public String getLocationString() { return fileStatus.getPath().toString(); }
public List<FileSystemBrowserTreeNode> buildAllPossibleTreeChildren() { ConnectionHandler connectionHandler = getConnectionHandler(); FileSystem fileSystem = connectionHandler.getMainFileSystem(); try { String path = fileStatus.getPath().toString(); FileStatus[] fileStatuses = fileSystem.listStatus(new Path(fileStatus.getPath().toString())); FileSystemBrowserTreeNode[] fileSystemBrowserTreeNodes = new FileSystemBrowserTreeNode[fileStatuses.length]; for (int i = 0; i < fileStatuses.length; i++) { FileStatus f = fileStatuses[i]; if (f.isDirectory()) { FileSystemObject dirdbObject = new HadoopDirectoryObject(this, f,f.getPath().getName()); fileSystemBrowserTreeNodes[i] = dirdbObject; } else { FileSystemObject filedbObject = new HadoopFileObject(this, f,f.getPath().getName()); fileSystemBrowserTreeNodes[i] = filedbObject; } } fileSystemBrowserTreeNodeLists = FileSystemBrowserUtils.createList(fileSystemBrowserTreeNodes); } catch (Exception ex) {
} return fileSystemBrowserTreeNodeLists; } }
|
HDFS的文件对象的实现HadoopFileObject。
和目录实现一样,唯一区别是 对象类型是文件类型并且文件是没有子对象的,但也要重写:
public List buildAllPossibleTreeChildren()
并且不能返回NULL。 代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
|
public class HadoopFileObject extends FileSystemObjectImpl { private List<FileSystemBrowserTreeNode> fileSystemBrowserTreeNodes =null; private FileStatus fileStatus;
public HadoopFileObject(FileSystemObject parentObject, org.apache.hadoop.fs.FileStatus resultSet, String name) { super(parentObject, resultSet,name); fileSystemBrowserTreeNodes = new ArrayList(); fileStatus = resultSet; }
public HadoopFileObject(ConnectionHandler connectionHandler, org.apache.hadoop.fs.FileStatus resultSet, String name) { super(connectionHandler, resultSet,name); fileSystemBrowserTreeNodes = new ArrayList(); fileStatus = resultSet; }
public String getLocationString() { return fileStatus.getPath().toString(); }
public FileSystemObjectType getObjectType() { return FileSystemObjectType.FILE; }
public List<FileSystemBrowserTreeNode> buildAllPossibleTreeChildren() { return fileSystemBrowserTreeNodes; } }
|
HDFS的根目录对象的实现FileSystemObjectBundleImpl。
该类继承树节点的抽象类FileSystemBrowserTreeNodeBase和FileSystemObjectBundle接口。该类,重点关注,怎么读取HDFS的根目录“/”对象,获取其数据进行绑定的。该类只有一个构造函数,在构造函数中通过 loadData()开始HDFS根目录的数据加载。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
|
public FileSystemObjectBundleImpl(ConnectionHandler connectionHandler, FileSystemBrowserTreeNode treeParent) { this.connectionHandler = connectionHandler; this.treeParent = treeParent; loadData(); }
public void loadData() { fileSystem = connectionHandler.getMainFileSystem(); if(connectionHandler.getConnectionStatus().isConnected()) { try { if( this.allPossibleTreeChildren!=null) { this.allPossibleTreeChildren.clear(); } FileStatus[] fileStatuses = fileSystem.listStatus(new Path("/")); FileSystemBrowserTreeNode[] fileSystemBrowserTreeNodes = new FileSystemBrowserTreeNode[fileStatuses.length]; for (int i = 0; i < fileStatuses.length; i++) { FileStatus f = fileStatuses[i]; if (f.isDirectory()) { FileSystemObject dirdbObject = new HadoopDirectoryObject(connectionHandler, f, f.getPath().getName()); fileSystemBrowserTreeNodes[i] = dirdbObject; } else { FileSystemObject filedbObject = new HadoopFileObject(connectionHandler, f, f.getPath().getName()); fileSystemBrowserTreeNodes[i] = filedbObject; } } this.allPossibleTreeChildren = FileSystemBrowserUtils.createList(fileSystemBrowserTreeNodes); } catch (Exception ex) { } } else { if( this.allPossibleTreeChildren!=null) { this.allPossibleTreeChildren.clear(); } } }
|