RapidMiner之Repository源码分析
Repository是存放process配置等元数据的地方,按惯例,先上UML图:
图1:Repository UML图
下面以LocalRepository为例来说明Repository是如何实现的,其它类型的Repository都是与此类似的:
首先来看下UML中的接口:
Entry:表示存储库中的一条记录,既可以是一个目录,也可以是一条数据项(叶子节点)
这个接口中的方法,看其英文注释就能明白其作用,RepositoryLocation这个类的作用是记录entry在repository中的位置,其格式为//Repository/path/to/object
public interface Entry { /** Returns the name, the last part of the location. */ public String getName(); /** Returns a string describing the type: "folder", "data", "blob", or "process". */ public String getType(); /** Returns the user name of the owner. */ public String getOwner(); /** Returns a human readable description. */ public String getDescription(); /** Returns true if this entry cannot be written to. */ public boolean isReadOnly(); /** Changes the name of the entry. The entry stays in the same folder. * @throws RepositoryException */ public boolean rename(String newName) throws RepositoryException; /** Needs to be implemented only for folders in the same repository. * Moving between different repositories is implemented by * {@link RepositoryManager#move(RepositoryLocation, Folder, com.rapidminer.tools.ProgressListener)} * using a sequence of copy and delete. * @throws RepositoryException */ public boolean move(Folder newParent) throws RepositoryException; /** Needs to be implemented only for folders in the same repository. * Moving between different repositories is implemented by * {@link RepositoryManager#move(RepositoryLocation, Folder, com.rapidminer.tools.ProgressListener)} * using a sequence of copy and delete. * @param newName New name for moved entry. If moved entry shouldn't be renamed: newName=null. * @throws RepositoryException */ public boolean move(Folder newParent, String newName) throws RepositoryException; /** Returns the folder containing this entry. */ public Folder getContainingFolder(); /** Subclasses can use this method to signal whether getting information * from this entry will block the current thread, e.g. because information must * be fetched over the network. */ public boolean willBlock(); /** A location, that can be used, e.g. as a parameter in the {@link RepositorySource} or which can be used * to locate the entry using {@link RepositoryManager#resolve(String)}. */ public RepositoryLocation getLocation(); /** Deletes the entry and its contents from the repository. * @throws RepositoryException */ public void delete() throws RepositoryException; /** Returns custom actions to be displayed in this entry's popup menu. */ public Collection<Action> getCustomActions(); }
Folder:包含sub-entries的entry
Folder扩展了Entry接口,增加了获取该folder下entry、刷新folder、判断是否存在某个entry的方法。
public interface Folder extends Entry {
public static final String TYPE_NAME = "folder"; public List<DataEntry> getDataEntries() throws RepositoryException; public List<Folder> getSubfolders() throws RepositoryException; public void refresh() throws RepositoryException; public boolean containsEntry(String name) throws RepositoryException; public Folder createFolder(String name) throws RepositoryException; public IOObjectEntry createIOObjectEntry(String name, IOObject ioobject, Operator callingOperator, ProgressListener progressListener)
throws RepositoryException; public ProcessEntry createProcessEntry(String name, String processXML) throws RepositoryException; public BlobEntry createBlobEntry(String name) throws RepositoryException; /** Returns true iff a child with the given name exists and a {@link #refresh()} * would find this entry (or it is already loaded). * @throws RepositoryException */ public boolean canRefreshChild(String childName) throws RepositoryException; }
Repository:表示一个完整的存储库,由Folder和Entry组成
Repository扩展了Forder接口,增加了如下方法:
public interface Repository extends Folder { // 添加RepositoryListener,该listener用于监听添加、删除、修改entry事件和刷新folder事件 public void addRepositoryListener(RepositoryListener l); // 删除一个RepositoryListener public void removeRepositoryListener(RepositoryListener l); /**根据字符串路径获取一个Entry * This will return the entry if existing or null if it can't be found. */ public Entry locate(String string) throws RepositoryException; /** Returns some user readable information about the state of this repository. */ public String getState(); /** Returns the icon name for the repository. */ public String getIconName(); /** Returns a piece of XML to store the repository in a configuration file. */ public Element createXML(Document doc); public abstract boolean shouldSave(); /** Called after the repository is added. Currently unused, but may be useful. Was once * used to fetch JDBC connection entries from remote server. */ public void postInstall(); public void preRemove(); /** Returns true if the repository is configurable. In that case,*/ public boolean isConfigurable(); /** Creates a configuration panel.*/ public RepositoryConfigurationPanel makeConfigurationPanel(); }
LocalRepository是用户存放在本地文件系统中的存储库,从上面的UML图可以看出,LocalRepository继承自类SimpleFolder并实现了接口Repository, SimpleFolder继承自类SimpleEntry,所以在研究LocalRepository之前,要先研究下SimpleEntry和SimpleFolder是如何实现的:
SimpleEntry是Entry接口的抽象实现:
SimpleEntry定义了如下三个成员变量,并且由子类来调用该类的构造函数进行初始化:
private String name; private LocalRepository repository; private SimpleFolder containingFolder; SimpleEntry(String name, SimpleFolder containingFolder, LocalRepository repository) { this.name = name; this.repository = repository; this.containingFolder = containingFolder; }
SimpleEntry定义了二个抽象方法,handleRename和handleMove,分别用来处理重命名和移动事件,这二个方法需要在其子类实现,SimpleEntry类对Entry接口方法的实现中,调用到了这二个抽象类:
protected abstract void handleRename(String newName) throws RepositoryException; protected abstract void handleMove(Folder newParent, String newName) throws RepositoryException;
我的