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

Generated on Mon Jan 14 17:29:45 2008 for OpenMobileIS by  doxygen 1.5.4