posts - 4,  comments - 0,  trackbacks - 0
  2010年11月2日

这里LZ再做最后一次冲刺,如果能找到线索,就继续,找不到,就找华生。
今天问了Leader,To be Cruel
因为populateMap作用域是private,所以它只能在本地被调用。
我们看看都有谁调用了它!

1,  public void setProcessMap(Map map) {
    processMap.clear();
    populateMap(map, processMap);
  }

2,  public void setDiscardMap(Map map) {
    discardMap.clear();
    populateMap(map, discardMap);
  }
从前面大家知道这个populateMap是将它的第一个参数里面值传给它第二个参数里面的Map里面。
我们的线索就是我们的数据传到了哪里,我们就找哪里。
现在传到了Map里,那我们就找Map看谁和它有联系。
有三个方法和processMap有关系:

1,public List getProcessDestinations(IMessageProcessor processor) {
    List l = (List) processMap.get(processor);
    return l != null ? l : Collections.EMPTY_LIST;
  }
注意它返回的是一个list,它将传进来的参数作为key,然后返回一个MessageProcessor的List。

2,  protected IMessageProcessor getIfAlreadyAutoboxed(Object processor){
    Object boxed = null;
    Iterator ite = processMap.keySet().iterator();
    while(ite.hasNext()){
      Object key = ite.next();
      if(! (key instanceof Node)) continue;
      Node node = (Node) key;
      if(node.getProcessor().equals(processor)){
        boxed = node;
        break;
      }
    }
    return (IMessageProcessor) boxed; 
  }
作用是得到如果已经封装过了。
得到processMap的key集合,然后迭代,如果key是Node(第一次出场)的实例,就继续下一次迭代,否则

将key(强制)转化为Node。如果node.getProcessor()==processor,那就把node赋值给boxed。中断迭代

。返回的是一个IMessageProcessor。
3, public Object clone() throws CloneNotSupportedException {
    RoutingMap obj = (RoutingMap) super.clone();
    obj.processors = Collections.unmodifiableSet(processors);
    obj.processMap = Collections.unmodifiableMap(processMap);
    obj.discardMap = Collections.unmodifiableMap(discardMap);
    obj.exceptionMap = Collections.unmodifiableMap(exceptionMap);
    return obj;
  }
这个先不详细描述了

我们可以试着把重点放在第一个方法上,选中第一个方法,CTRL+ALT+H
发现出现了一个新的view,call hierarchy.
一共有4个调用。
先看第一个方法 在新类TopologyAnalyser中
  private void buildTopology(IRoutingMap map) {
    topology=new HashMap();
    Collection processors=map.getMessageProcessors();

    Iterator it=processors.iterator();
    //Get the direct connections
    while (it.hasNext()) {
      IMessageProcessor processor=(IMessageProcessor)it.next();
      link(processor,map.getProcessDestinations(processor));
      link(processor,map.getDiscardDestinations(processor));
    }
    //Now get the indirect ones
    it=processors.iterator();
  }
调用了RoutingMap里面的 
 public Collection getMessageProcessors() {
    return Collections.unmodifiableCollection(processors);
  }
这里面的
Collections.unmodifiableCollection返回指定 collection 的不可修改视图,此方法允许模块为用户提

供对内部 collection 的“只读”访问。在返回的 collection 上执行的查询操作将“读完”指定的

collection。试图修改返回的 collection(不管是直接修改还是通过其迭代器进行修改)将导致抛出

UnsupportedOperationException

processors值是xml传来的所有的IMessageProcessor。
迭代出所有的IMessageProcessor,
根据提供的IMessageProcessor key得到value List<IMessageProcessor>。

link(processor,map.getProcessDestinations(processor));将源处理器和目标处理器连接起来。
查找link()的源
private void link(IMessageProcessor src,List destinations) {
    TopologyInfo srcTi=getTopologyInfo(src);
    srcTi.addOutputs(destinations);
    Iterator it=destinations.iterator();
    while(it.hasNext()) {
      IMessageProcessor destination=(IMessageProcessor)it.next();
      TopologyInfo dstTi=getTopologyInfo(destination);
      dstTi.addInput(src);
    }
  }

TopololyInfo 是类TopologyAnalyser中一个内部类,作用就是得到输入和输出,并将输入和输出

的IMessageProcessor放入list中。
 class TopologyInfo {
    private List inputs=new ArrayList();
    private List outputs=new ArrayList();
 
    public List getInputs() {
      return inputs;
    }
    public List getOutputs(){return outputs;}
    public void addInput(IMessageProcessor input) {
      inputs.add(input);
    }
    public void addOutput(IMessageProcessor output) {outputs.add(output);}
    //public void addInputs(Collection inputs) {this.inputs.addAll(inputs);}
    public void addOutputs(Collection outputs) {this.outputs.addAll(outputs);} 
  }
我们再回头看link()的源,将目的处理器给了srcTi的outputs List.源处理器给了inputs List。
在这里源和目的终于连接上了。

那么这个类TopologyAnalyser,在link()中要初始化,
首先调用
  private TopologyInfo getTopologyInfo(IMessageProcessor processor) {
    TopologyInfo topologyInfo;
    if (!topology.containsKey(processor)) {
      topologyInfo=new TopologyInfo();
      topology.put(processor, topologyInfo);
    }
    else {
      topologyInfo=(TopologyInfo)topology.get(processor);
    }
    return topologyInfo;
  }
如果在Map topology中包含源IMessageProcessor,则将topology中的目标IMessageProcessor放

入topologyInfo中,如果不包含IMessageProcessor,则创建一个新的TopologyInfo实例,然后将空

的topologyInfo和源ImessageProcessor一起放入topology Map。返回topologyInfo.

posted @ 2010-11-03 13:54 Vigoss 阅读(177) | 评论 (0)编辑 收藏

好了,老子不废话了,真金不怕卖钱。
Router bean下有property 名叫processors,所以应该也有个set方法,不然没有办法设置值。我们找到
org.openadaptor.core.router.Router类。
不负众望
  public void setProcessors(List processorList){
    // create process map from list of processors
    if ((processorList==null) || (processorList.isEmpty())) {
      throw new RuntimeException("Null or empty processorList is not permitted");
    }
    Object[] processors=processorList.toArray(new Object[processorList.size()]);
    Map processMap = new HashMap();
    for (int i=1;i<processors.length;i++){
      processMap.put(processors[i-1],processors[i]);
    }
    setProcessMap(processMap);
  }
果然有,大家通过简单阅读代码可以看到这就是个将List设置到Map的过程,那么Map有什么用呢?大家再

仔细看看,不要着急,对了,看到了吧,那个for(;;),它是将一个处理器接着一个处理器塞

到HashMap里面,前面的是顺序用个鲜明的矩阵图来形容吧
  1  2
  2  3
  3  4
  4  5
发现什么规律?右边的减左边的等于1,- -,你真不是盖的。
大家想想HashMap的结构是什么样的?<key,value>!
对!
当它循着这个Map的key找的时候会找到value,然后又以这个value为key接着找下一个value,循环直到这

个Map的最后一个值。这样就会把每个processor都执行一遍。
那么有人会问- -!为什么说会这样执行,你怎么知道啊?
好的,来看
setProcessors()里最后一行是什么?
setProcessMap()
好,继续找它,对,还在Router里
  public void setProcessMap(Map map) {
    if (processMapConfigured) {
      throw new RuntimeException("Only one of processMap and processors properties may be

configured");
    }
    processMapConfigured=true;
    routingMap.setProcessMap(map);
  }
对,继续
这里设置了processMapConfigured=true;这是为什么呢?LZ下次为你揭开这个神秘的擦脚布。
先把注意力放在routingMap里,它的本类是RoutingMap
好,找到
  RoutingMap,找到setProcessMap()
  public void setProcessMap(Map map) {
    processMap.clear();
    populateMap(map, processMap);
  }
注意populateMap(map,processMap)在执行前,processMap是空的
在这里我们发现了processMap的定义,Sets the processMap which defines how to route output from

one adaptor component to anothers.
是一个定义怎样将一个适配器组件的输出转发到另外一个的集合
首先它把processMap清空了,然后populateMap(map,processMap)
哇擦,天长地久有时尽 程序绵绵无绝期
找到populateMap(map,processMap)

  private void populateMap(Map map, Map checkedMap) {
    map = autoboxer.autobox(map);
    for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) {
      Map.Entry entry = (Map.Entry) iter.next();
      verifyEntryKeyIsIMessageProcessor(entry);
      IMessageProcessor fromProcessor = (IMessageProcessor) entry.getKey();
      List processorList = autoboxIMessageProcessorList(entry.getValue());
      processors.add(fromProcessor);
      processors.addAll(processorList);
      checkedMap.put(fromProcessor, processorList);
    }
  }
大家仔细阅读代码发现这就是个将map中的数据先verifyEntryKeyIsIMessageProcessor(entry);
确定map的key是否是MessageProcessor,不是就报错退出了,是就将他强制转换为IMessageProcessor,

然后自动封装,这里真j8操淡,TMD前面设置到Map里面的时候就可以了,现在还要设置到set中,还来个

什么自动封箱,封你妈啊,不过他们也有道理,如果list里面嵌套了另外一个list就把第二

个list的MessageProcessor给漏掉了。现在checkMap里面已经有了所有的MessageProcessor,LZ就要看看

他们要干什吗?

posted @ 2010-11-02 17:39 Vigoss 阅读(199) | 评论 (0)编辑 收藏
<2010年11月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

常用链接

留言簿(2)

随笔档案

搜索

  •  

最新评论

阅读排行榜

评论排行榜