DependTree.java

00001 /*
00002  * OpenMobileIS - a free Java(TM) Framework for mobile applications Java(TM)
00003  * Copyright (C) 2004-2006 Philippe Delrieu
00004  * All rights reserved.
00005  * Contact: pdelrieu@openmobileis.org
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.common.util.collection.tree;
00026 
00027 import org.openmobileis.common.util.collection.Array;
00028 
00036 public final class DependTree {
00037   private DependTreePhaseList firstPhase, currentPhase;
00038   private static Array emptyArray = new Array();
00039 
00043   public DependTree() {
00044     super();
00045   }
00046   
00047   public void clearTree() {
00048           emptyArray.clear();
00049           firstPhase=null;
00050           currentPhase=null;
00051   }
00052   
00053   public Object getObjectByName(String listenerName) {
00054     DependTreePhaseList phase = firstPhase;
00055     while (phase != null) {
00056       DependNode node = this.getNodeFromPhaseList(listenerName);
00057       if (node != null) {
00058         return node.nodeObject;
00059       }
00060       phase = phase.nextPhase;
00061     }
00062     return null;
00063   }
00064   
00065   public void addObject(String name, Object object, String[] dependList) {
00066     if (firstPhase == null)  {
00067       firstPhase = new DependTreePhaseList(1);
00068     }
00069     Array depends = null;
00070     if (dependList == null) {
00071       depends = emptyArray;
00072     } else  {
00073      depends = new Array(dependList);
00074     }
00075     //first add listener dependance.
00076     Array depArray = new Array();
00077     int dependssize = depends.size();
00078     for (int i=0; i<dependssize; i++)  {
00079      DependNode depnode = new DependNode();
00080      depnode.nodeName = (String)depends.get(i);
00081      this.addDependNodeToList(depArray, firstPhase, depnode); 
00082     }
00083     //add new listener
00084     DependNode newnode = new DependNode();
00085     newnode.nodeName = name;
00086     newnode.nodeObject = object;
00087     
00088     //process depends will not all treated. Always end because all depends has already been added.
00089     do  {
00090       depends = this.addDependNodeToList(depends, firstPhase, newnode);  
00091     } while (depends.size() != 0);
00092   }
00093   
00094   public void resetPhaseList()  {
00095     //set all synchro listener node to OK
00096     DependTreePhaseList phase = firstPhase;
00097     while (phase != null) {
00098       int size = phase.nodeList.size();
00099       for (int i=0; i<size; i++)  {
00100         DependNode node = (DependNode) phase.nodeList.get(i);
00101         node.validState = true;
00102       }
00103       phase = phase.nextPhase;
00104     }
00105     currentPhase = firstPhase;
00106   }
00107   
00108   public Array getNextPhaseObjectList()  {
00109     if (currentPhase == null) return DependTree.emptyArray;
00110     Array listenerList = new Array();
00111     //remove not ok listener
00112     int size = currentPhase.nodeList.size();
00113     for (int i=0; i<size; i++)  {
00114       DependNode node = (DependNode) currentPhase.nodeList.get(i);
00115       if (node.validState)  {
00116         listenerList.add(node.nodeObject);
00117       }
00118     }
00119     currentPhase = currentPhase.nextPhase;
00120     return listenerList;
00121  }
00122   
00123   public void invalidateNode(String listenerName) {
00124     DependNode listener = this.getNodeFromPhaseList(listenerName);
00125     if (listener != null) {
00126       invalidDependNodeChilds(listener);
00127     }
00128   }
00129   
00130   protected void invalidDependNodeChilds(DependNode listener)  {
00131     listener.validState = false;
00132     int size = listener.nexts.size();
00133     for (int i=0; i<size; i++)  {
00134       this.invalidDependNodeChilds((DependNode)listener.nexts.get(i));
00135     }
00136   }
00137   
00138   private DependNode getNodeFromPhaseList(String listenerName)  {
00139     DependTreePhaseList phase = firstPhase;
00140     while (phase != null) {
00141       int size = phase.nodeList.size();
00142       for (int i=0; i<size; i++)  {
00143         DependNode node = (DependNode) phase.nodeList.get(i);
00144         if (node.nodeName.equals(listenerName)) {
00145           return node;
00146         }
00147       }
00148       phase = phase.nextPhase;
00149     }
00150     return null;
00151   }
00152   
00153   private Array addDependNodeToList(Array depends, DependTreePhaseList phase, DependNode newnode) {
00154           
00155     int phasesize = phase.nodeList.size();
00156     DependNode phaseNode = null;
00157    
00158    //test if node already present process already added node
00159     for (int j=0; j<phasesize; j++)  {
00160       phaseNode = (DependNode)phase.nodeList.get(j);
00161       if (newnode.nodeName.equals(phaseNode.nodeName)) {
00162         if (newnode.nodeObject != null) {
00163           phaseNode.nodeObject = newnode.nodeObject;
00164         }
00165         // node already in a phase, use already added node to keep node context data.
00166          newnode = phaseNode;
00167       }    
00168     }
00169     
00170     //if no dependence add listener
00171     if (depends.size() == 0)  {
00172       //validate if not already added in posterior phase.
00173       if ((newnode.nodePhase != null) && (newnode.nodePhase.phaseNumber < phase.phaseNumber)) {
00174         newnode.nodePhase.nodeList.remove(newnode);
00175         newnode.nodePhase = null;
00176       }
00177       //if not in a phase add it. //we suppose that all dependance has been added.
00178       if (newnode.nodePhase == null)  {
00179         //only add if not already added. Avoid multiple depend add.
00180         if(this.getNodeFromPhaseList(newnode.nodeName)== null)  {
00181           newnode.nodePhase = phase;
00182           phase.nodeList.add(newnode);
00183           if (newnode.nexts.size() >0)  {
00184             //move all dependant listerner to next phase and dependent dependant listener and so on.
00185             movedependentListenerTonextPhase(newnode);
00186           }
00187         }
00188       }
00189       return DependTree.emptyArray;
00190     }   
00191     
00192     // validate dependance if depend listener is already registered
00193    Array newdepends = (Array)depends.clone();
00194    int dependssize = depends.size();
00195    
00196    Array clonePhaseNodeList = (Array) phase.nodeList.clone();
00197    for (int i=0; i<dependssize; i++)  {
00198       for (int j=0; j<phasesize; j++)  {
00199         phaseNode = (DependNode)clonePhaseNodeList.get(j);
00200         // test if depends are in this phase.
00201         if (depends.get(i).equals(phaseNode.nodeName)) {
00202           newdepends.remove(phaseNode.nodeName);
00203           phaseNode.nexts.add(newnode);
00204           if (phase.nextPhase == null)  {
00205             phase.nextPhase = new DependTreePhaseList(phase.phaseNumber+1);
00206           }
00207           newdepends = this.addDependNodeToList(newdepends, phase.nextPhase, newnode);
00208         }
00209       }
00210       if ((phase.nextPhase != null) && (depends.size() >0))  { //perhaps depends are in next phase.
00211         newdepends = this.addDependNodeToList(newdepends, phase.nextPhase, newnode);
00212       }
00213     }    
00214     return newdepends;
00215   }
00216 
00217   private void movedependentListenerTonextPhase(DependNode node)  {
00218     Array othernodelist = node.nexts;
00219     node.nexts = new Array();
00220     Array newdepends = new Array();
00221     newdepends.add(node.nodeName);
00222     for (int i=0; i<othernodelist.size(); i++)  {
00223       DependNode listener = (DependNode) othernodelist.get(i);
00224       
00225       //PB if depend are in next Phase not added.
00226       this.addDependNodeToList(newdepends, listener.nodePhase, listener);
00227       this.movedependentListenerTonextPhase(listener);
00228     }
00229     
00230   }
00231 }
00232 
00233 

Generated on Tue May 22 23:01:08 2007 for OpenMobileIS by  doxygen 1.5.1-p1