现在的位置: 首页 > 综合 > 正文

利用JNI监控CVS仓库变动,自动更新到相应目录——简化WEB小组开发(二、架构篇)

2018年05月21日 ⁄ 综合 ⁄ 共 4896字 ⁄ 字号 评论关闭
 测试完成后,我们开始着手架构分析(测试先行)

在这个简单的系统中,我们把模块分成3块

第一:监听者,无非是很多的线程,用来监听各式各样的文件以及要满足各式各样的监听规则

第二:执行者,当监听者要去触发事件时,交给哪个执行者,注意,监听者可以有很多个执行者

第三:容器,它负责维护监听者和执行者,以及它们的生命周期管理

监听者们统一继承一个 CommonListener

package wxy.tool.filewatcher.Listener;

import wxy.tool.filewatcher.FileWatcherNative;
import wxy.tool.filewatcher.Exception.ListenError;

public abstract class  CommonListener  implements Runnable {
    
private long handle;
    
    
private int filter;
    
private String path;
    
private Boolean subtree;
    
    
public CommonListener(String path,Boolean subtree,int filter) {
        
this.path = path;
        
this.subtree = subtree;
        
this.filter=filter;
    }


    
abstract protected void whenChange();

    
public void run() {
        
try {
            handle 
= FileWatcherNative.FindFirstChangeNotification(
                    path, subtree, filter);
            
            
int returnState; 
            
while(true){
                FileWatcherNative.FindNextChangeNotification(handle);
                
                returnState 
= FileWatcherNative.WaitForSingleObject(
                        handle, FileWatcherNative.INFINITE);
                
                
if(FileWatcherNative.WAIT_OBJECT_0 == returnState)
                    whenChange();
                
else
                    
throw new ListenError("监听超时或者被取消");
            }

        }
 catch (Exception e) {
            e.printStackTrace();
        }

        
        
    }

    
}

所以的监听者都必须继承这个父类,它把run里的公共方法抽象出来了

下面我们写2个监听者,第一个可以监听文件的名字改变,第二个可以监听是否有写入数据的行为

package wxy.tool.filewatcher.Listener;


public class ChangeFileNameListener extends CommonListener{
    
    
public ChangeFileNameListener(String path,Boolean subtree) {
        
super(path,subtree,0x00000001);
    }


    @Override
    
protected void whenChange() {
        System.out.println(
this+" want do something");
    }


}

package wxy.tool.filewatcher.Listener;

import wxy.tool.filewatcher.MainContainer;

public class LastWriteListener extends CommonListener {
    
    
private MainContainer container;

    
public LastWriteListener(String path,Boolean subtree) {
        
super(path, subtree, 0x00000010);
    }

    
    @Override
    
public void whenChange() {
        container.fire(
this);
    }


    
public void setContainer(MainContainer container) {
        
this.container = container;
    }

    
}

接着是Action,这里还是一个雏形

package wxy.tool.filewatcher.Action;

/**
 * 
@author wxy
 *    注意要考虑线程同步问题,这里的Action可能会被多个线程一起调用
 
*/

public interface Action {
    
public void excute();
}

package wxy.tool.filewatcher.Action;

public class DefaultAction implements Action {

    @Override
    
public void excute() {
        System.out.println(
"excute default action");
    }


}

最后是这个容器,同样也只是雏形而已,只是添加监听者和绑定执行者

package wxy.tool.filewatcher;

import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

import wxy.tool.filewatcher.Action.Action;
import wxy.tool.filewatcher.Action.DefaultAction;
import wxy.tool.filewatcher.Exception.NoListenerException;
import wxy.tool.filewatcher.Listener.ChangeFileNameListener;
import wxy.tool.filewatcher.Listener.CommonListener;
import wxy.tool.filewatcher.Listener.LastWriteListener;

public class MainContainer {
    
    
private ConcurrentHashMap<CommonListener,Thread> listenersMap = 
                 
new ConcurrentHashMap<CommonListener,Thread>();
    
    
private ConcurrentHashMap<CommonListener,Collection<Action>> listenerActionMap =
                 
new ConcurrentHashMap<CommonListener,Collection<Action>>();
    
    
public void beginWatch(){
        
        
if(listenersMap.size()<1){
            
throw new NoListenerException("没有监听者");
        }
else{
            Collection
<Thread> listeners = listenersMap.values();
            
for(Thread listener : listeners){
                listener.setDaemon(
true);
                listener.start();
            }

        }

    }


    
public void addListener(CommonListener listener) {
        listenersMap.put(listener,
new Thread(listener));
        bindActions(listener, 
new Action[]{new DefaultAction()});
    }

    
    
public void bindActions(CommonListener listener,Action[] actions){
        Collection
<Action> actionQueue = 
            
new ConcurrentLinkedQueue<Action>(Arrays.asList(actions));
        listenerActionMap.put(listener, actionQueue);
    }

    
    
public void fire(CommonListener listener){
        
for(Action action : listenerActionMap.get(listener)){
            action.excute();
        }

    }

    
    
public static void main(String[] args) throws Exception {
        MainContainer container 
= new MainContainer();
        container.addListener(
new ChangeFileNameListener("D:/",true));
        LastWriteListener listener1 
= new LastWriteListener("D:/",true); 
        listener1.setContainer(container);
        container.addListener(listener1);
        container.beginWatch();
        Thread.sleep(Long.MAX_VALUE);
        
    }

    
    
}

抱歉!评论已关闭.