Main Page | Packages | Class Hierarchy | Class List | Directories | File List | Class Members | Related Pages

ListenerOrdonancer.java

00001 /*
00002  * OpenMobileIS - a free Java(TM) Framework for mobile applications Java(TM)
00003  * Copyright (C) 2004-2005 Philippe Delrieu
00004  * All rights reserved.
00005  * Contact: openmobileis@e-care.fr
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
00020  * USA
00021  *
00022  *  Author : Philippe Delrieu
00023  * 
00024  */
00025 package org.openmobileis.synchro.openmsp.client.core;
00026 
00027 import org.openmobileis.common.util.collection.Array;
00028 import org.openmobileis.synchro.openmsp.client.OpenMSPSyncListener;
00029 
00037 public final class ListenerOrdonancer {
00038   private ListenerPhaseList firstPhase, currentPhase;
00039   private static final Array emptyArray = new Array();
00040 
00044   public ListenerOrdonancer() {
00045     super();
00046   }
00047   
00048   public OpenMSPSyncListener getListenerByName(String listenerName) {
00049     ListenerPhaseList phase = firstPhase;
00050     while (phase != null) {
00051       ListenerNode node = this.getNodeFromPhaseList(listenerName);
00052       if (node != null) {
00053         return node.listener;
00054       }
00055       phase = phase.nextPhase;
00056     }
00057     return null;
00058   }
00059   
00060   public void addListener(OpenMSPSyncListener listener, String[] dependList) {
00061     if (firstPhase == null)  {
00062       firstPhase = new ListenerPhaseList(1);
00063     }
00064     Array depends = null;
00065     if (dependList == null) {
00066       depends = emptyArray;
00067     } else  {
00068      depends = new Array(dependList);
00069     }
00070     //first add listener dependance.
00071     Array depArray = new Array();
00072     int dependssize = depends.size();
00073     for (int i=0; i<dependssize; i++)  {
00074      ListenerNode depnode = new ListenerNode();
00075      depnode.listenerName = (String)depends.get(i);
00076      this.addListenerToList(depArray, firstPhase, depnode); 
00077     }
00078     //add new listener
00079     ListenerNode newnode = new ListenerNode();
00080     newnode.listenerName = listener.getSyncName();
00081     newnode.listener = listener;
00082     
00083     //process depends will not all treated. Always end because all depends has already been added.
00084     do  {
00085       depends = this.addListenerToList(depends, firstPhase, newnode);  
00086     } while (depends.size() != 0);
00087   }
00088   
00089   public void beginSynchro()  {
00090     //set all synchro listener node to OK
00091     ListenerPhaseList phase = firstPhase;
00092     while (phase != null) {
00093       int size = phase.nodeList.size();
00094       for (int i=0; i<size; i++)  {
00095         ListenerNode node = (ListenerNode) phase.nodeList.get(i);
00096         node.validState = true;
00097       }
00098       phase = phase.nextPhase;
00099     }
00100     currentPhase = firstPhase;
00101   }
00102   
00103   public void endSynchro()  {
00104   }
00105   
00106   public Array getNextListenerList()  {
00107     if (currentPhase == null) return ListenerOrdonancer.emptyArray;
00108     Array listenerList = new Array();
00109     //remove not ok listener
00110     int size = currentPhase.nodeList.size();
00111     for (int i=0; i<size; i++)  {
00112       ListenerNode node = (ListenerNode) currentPhase.nodeList.get(i);
00113       if (node.validState)  {
00114         listenerList.add(node.listener);
00115       }
00116     }
00117     currentPhase = currentPhase.nextPhase;
00118     return listenerList;
00119  }
00120   
00121   public void notifySynchroError(String listenerName) {
00122     ListenerNode listener = this.getNodeFromPhaseList(listenerName);
00123     if (listener != null) {
00124       invalidListenerChilds(listener);
00125     }
00126   }
00127   
00128   private void invalidListenerChilds(ListenerNode listener)  {
00129     listener.validState = false;
00130     int size = listener.nexts.size();
00131     for (int i=0; i<size; i++)  {
00132       this.invalidListenerChilds((ListenerNode)listener.nexts.get(i));
00133     }
00134   }
00135   
00136   private ListenerNode getNodeFromPhaseList(String listenerName)  {
00137     ListenerPhaseList phase = firstPhase;
00138     while (phase != null) {
00139       int size = phase.nodeList.size();
00140       for (int i=0; i<size; i++)  {
00141         ListenerNode node = (ListenerNode) phase.nodeList.get(i);
00142         if (node.listenerName.equals(listenerName)) {
00143           return node;
00144         }
00145       }
00146       phase = phase.nextPhase;
00147     }
00148     return null;
00149   }
00150   
00151   private Array addListenerToList(Array depends, ListenerPhaseList phase, ListenerNode newnode) {
00152           
00153     int phasesize = phase.nodeList.size();
00154     ListenerNode phaseNode = null;
00155    
00156    //test if node already present process already added node
00157     for (int j=0; j<phasesize; j++)  {
00158       phaseNode = (ListenerNode)phase.nodeList.get(j);
00159       if (newnode.listenerName.equals(phaseNode.listenerName)) {
00160         if (newnode.listener != null) {
00161           phaseNode.listener = newnode.listener;
00162         }
00163         // node already in a phase, use already added node to keep node context data.
00164          newnode = phaseNode;
00165       }    
00166     }
00167     
00168     //if no dependence add listener
00169     if (depends.size() == 0)  {
00170       //validate if not already added in posterior phase.
00171       if ((newnode.nodePhase != null) && (newnode.nodePhase.phaseNumber < phase.phaseNumber)) {
00172         newnode.nodePhase.nodeList.remove(newnode);
00173         newnode.nodePhase = null;
00174       }
00175       //if not in a phase add it. //we suppose that all dependance has been added.
00176       if (newnode.nodePhase == null)  {
00177         //only add if not already added. Avoid multiple depend add.
00178         if(this.getNodeFromPhaseList(newnode.listenerName)== null)  {
00179           newnode.nodePhase = phase;
00180           phase.nodeList.add(newnode);
00181           if (newnode.nexts.size() >0)  {
00182             //move all dependant listerner to next phase and dependent dependant listener and so on.
00183             movedependentListenerTonextPhase(newnode);
00184           }
00185         }
00186       }
00187       return ListenerOrdonancer.emptyArray;
00188     }   
00189     
00190     // validate dependance if depend listener is already registered
00191    Array newdepends = (Array)depends.clone();
00192    int dependssize = depends.size();
00193    
00194    Array clonePhaseNodeList = (Array) phase.nodeList.clone();
00195    for (int i=0; i<dependssize; i++)  {
00196       for (int j=0; j<phasesize; j++)  {
00197         phaseNode = (ListenerNode)clonePhaseNodeList.get(j);
00198         // test if depends are in this phase.
00199         if (depends.get(i).equals(phaseNode.listenerName)) {
00200           newdepends.remove(phaseNode.listenerName);
00201           phaseNode.nexts.add(newnode);
00202           if (phase.nextPhase == null)  {
00203             phase.nextPhase = new ListenerPhaseList(phase.phaseNumber+1);
00204           }
00205           newdepends = this.addListenerToList(newdepends, phase.nextPhase, newnode);
00206         }
00207       }
00208       if ((phase.nextPhase != null) && (depends.size() >0))  { //perhaps depends are in next phase.
00209         newdepends = this.addListenerToList(newdepends, phase.nextPhase, newnode);
00210       }
00211     }    
00212     return newdepends;
00213   }
00214 
00215   private void movedependentListenerTonextPhase(ListenerNode node)  {
00216     Array othernodelist = node.nexts;
00217     node.nexts = new Array();
00218     Array newdepends = new Array();
00219     newdepends.add(node.listenerName);
00220     for (int i=0; i<othernodelist.size(); i++)  {
00221       ListenerNode listener = (ListenerNode) othernodelist.get(i);
00222       
00223       //PB if depend are in next Phase not added.
00224       this.addListenerToList(newdepends, listener.nodePhase, listener);
00225       this.movedependentListenerTonextPhase(listener);
00226     }
00227     
00228   }
00229 }
00230 
00231 

Generated on Wed Dec 14 21:05:34 2005 for OpenMobileIS by  doxygen 1.4.4