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

Generated on Mon Dec 4 11:03:26 2006 for OpenMobileIS by  doxygen 1.5.1-p1