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 void setInactivateObjectByName(String listenerName, boolean inactif) {
00055     DependTreePhaseList phase = firstPhase;
00056     while (phase != null) {
00057       DependNode node = this.getNodeFromPhaseList(listenerName);
00058       if (node != null) {
00059         node.inactif = inactif;
00060       }
00061       phase = phase.nextPhase;
00062     }
00063   }
00064   
00065   public Object getObjectByName(String listenerName) {
00066     DependTreePhaseList phase = firstPhase;
00067     while (phase != null) {
00068       DependNode node = this.getNodeFromPhaseList(listenerName);
00069       if (node != null) {
00070         return node.nodeObject;
00071       }
00072       phase = phase.nextPhase;
00073     }
00074     return null;
00075   }
00076   
00077   public void addObject(String name, Object object, String[] dependList) {
00078     if (firstPhase == null)  {
00079       firstPhase = new DependTreePhaseList(1);
00080     }
00081     Array depends = null;
00082     if (dependList == null) {
00083       depends = emptyArray;
00084     } else  {
00085      depends = new Array(dependList);
00086     }
00087     //first add listener dependance.
00088     Array depArray = new Array();
00089     int dependssize = depends.size();
00090     for (int i=0; i<dependssize; i++)  {
00091      DependNode depnode = new DependNode();
00092      depnode.nodeName = (String)depends.get(i);
00093      this.addDependNodeToList(depArray, firstPhase, depnode); 
00094     }
00095     //add new listener
00096     DependNode newnode = new DependNode();
00097     newnode.nodeName = name;
00098     newnode.nodeObject = object;
00099     
00100     //process depends will not all treated. Always end because all depends has already been added.
00101     do  {
00102       depends = this.addDependNodeToList(depends, firstPhase, newnode);  
00103     } while (depends.size() != 0);
00104   }
00105   
00106   public void resetPhaseList()  {
00107     //set all synchro listener node to OK
00108     DependTreePhaseList phase = firstPhase;
00109     while (phase != null) {
00110       int size = phase.nodeList.size();
00111       for (int i=0; i<size; i++)  {
00112         DependNode node = (DependNode) phase.nodeList.get(i);
00113         node.validState = true;
00114       }
00115       phase = phase.nextPhase;
00116     }
00117     currentPhase = firstPhase;
00118   }
00119   
00120   public Array getNextPhaseObjectList()  {
00121     if (currentPhase == null) return DependTree.emptyArray;
00122     Array listenerList = new Array();
00123     //remove not ok listener
00124     int size = currentPhase.nodeList.size();
00125     for (int i=0; i<size; i++)  {
00126       DependNode node = (DependNode) currentPhase.nodeList.get(i);
00127       if (node.validState && !node.inactif)  {
00128         listenerList.add(node.nodeObject);
00129       }
00130     }
00131     currentPhase = currentPhase.nextPhase;
00132     return listenerList;
00133  }
00134   
00135   public void invalidateNode(String listenerName) {
00136     DependNode listener = this.getNodeFromPhaseList(listenerName);
00137     if (listener != null) {
00138       invalidDependNodeChilds(listener);
00139     }
00140   }
00141   
00142   protected void invalidDependNodeChilds(DependNode listener)  {
00143     listener.validState = false;
00144     int size = listener.nexts.size();
00145     for (int i=0; i<size; i++)  {
00146       this.invalidDependNodeChilds((DependNode)listener.nexts.get(i));
00147     }
00148   }
00149   
00150   private DependNode getNodeFromPhaseList(String listenerName)  {
00151     DependTreePhaseList phase = firstPhase;
00152     while (phase != null) {
00153       int size = phase.nodeList.size();
00154       for (int i=0; i<size; i++)  {
00155         DependNode node = (DependNode) phase.nodeList.get(i);
00156         if (node.nodeName.equals(listenerName)) {
00157           return node;
00158         }
00159       }
00160       phase = phase.nextPhase;
00161     }
00162     return null;
00163   }
00164   
00165   private Array addDependNodeToList(Array depends, DependTreePhaseList phase, DependNode newnode) {
00166           
00167     int phasesize = phase.nodeList.size();
00168     DependNode phaseNode = null;
00169    
00170    //test if node already present process already added node
00171     for (int j=0; j<phasesize; j++)  {
00172       phaseNode = (DependNode)phase.nodeList.get(j);
00173       if (newnode.nodeName.equals(phaseNode.nodeName)) {
00174         if (newnode.nodeObject != null) {
00175           phaseNode.nodeObject = newnode.nodeObject;
00176         }
00177         // node already in a phase, use already added node to keep node context data.
00178          newnode = phaseNode;
00179       }    
00180     }
00181     
00182     //if no dependence add listener
00183     if (depends.size() == 0)  {
00184       //validate if not already added in posterior phase.
00185       if ((newnode.nodePhase != null) && (newnode.nodePhase.phaseNumber < phase.phaseNumber)) {
00186         newnode.nodePhase.nodeList.remove(newnode);
00187         newnode.nodePhase = null;
00188       }
00189       //if not in a phase add it. //we suppose that all dependance has been added.
00190       if (newnode.nodePhase == null)  {
00191         //only add if not already added. Avoid multiple depend add.
00192         if(this.getNodeFromPhaseList(newnode.nodeName)== null)  {
00193           newnode.nodePhase = phase;
00194           phase.nodeList.add(newnode);
00195           if (newnode.nexts.size() >0)  {
00196             //move all dependant listerner to next phase and dependent dependant listener and so on.
00197             movedependentListenerTonextPhase(newnode);
00198           }
00199         }
00200       }
00201       return DependTree.emptyArray;
00202     }   
00203     
00204     // validate dependance if depend listener is already registered
00205    Array newdepends = (Array)depends.clone();
00206    int dependssize = depends.size();
00207    
00208    Array clonePhaseNodeList = (Array) phase.nodeList.clone();
00209    for (int i=0; i<dependssize; i++)  {
00210       for (int j=0; j<phasesize; j++)  {
00211         phaseNode = (DependNode)clonePhaseNodeList.get(j);
00212         // test if depends are in this phase.
00213         if (depends.get(i).equals(phaseNode.nodeName)) {
00214           newdepends.remove(phaseNode.nodeName);
00215           phaseNode.nexts.add(newnode);
00216           if (phase.nextPhase == null)  {
00217             phase.nextPhase = new DependTreePhaseList(phase.phaseNumber+1);
00218           }
00219           newdepends = this.addDependNodeToList(newdepends, phase.nextPhase, newnode);
00220         }
00221       }
00222       if ((phase.nextPhase != null) && (depends.size() >0))  { //perhaps depends are in next phase.
00223         newdepends = this.addDependNodeToList(newdepends, phase.nextPhase, newnode);
00224       }
00225     }    
00226     return newdepends;
00227   }
00228 
00229   private void movedependentListenerTonextPhase(DependNode node)  {
00230     Array othernodelist = node.nexts;
00231     node.nexts = new Array();
00232     Array newdepends = new Array();
00233     newdepends.add(node.nodeName);
00234     for (int i=0; i<othernodelist.size(); i++)  {
00235       DependNode listener = (DependNode) othernodelist.get(i);
00236       
00237       //PB if depend are in next Phase not added.
00238       this.addDependNodeToList(newdepends, listener.nodePhase, listener);
00239       this.movedependentListenerTonextPhase(listener);
00240     }
00241     
00242   }
00243   
00244   //ADD
00245   public Array getAllObjects() {
00246             DependTreePhaseList phase = firstPhase;
00247             Array arrayObject = new Array();
00248             while (phase != null) {
00249               Array arrayNode = this.getAllNodesFromPhaseList();
00250               if (arrayNode != null) {
00251                 for(int i=0;i<arrayNode.size();i++){
00252                         DependNode node = (DependNode)arrayNode.get(i);
00253                         arrayObject.add(node.nodeObject);
00254                 }
00255               }
00256               phase = phase.nextPhase;
00257             }
00258             return arrayObject;
00259   }
00260   
00261   //ADD
00262   private Array getAllNodesFromPhaseList()  {
00263             DependTreePhaseList phase = firstPhase;
00264             Array array = new Array();
00265             while (phase != null) {
00266               int size = phase.nodeList.size();
00267               for (int i=0; i<size; i++)  {
00268                 DependNode node = (DependNode) phase.nodeList.get(i);
00269                 if (node != null) {
00270                   array.add(node);
00271                 }
00272               }
00273               phase = phase.nextPhase;
00274             }
00275             return array;
00276   }
00277   
00284   public boolean removeObjectByName(String nodeName)  {
00285             DependTreePhaseList phase = firstPhase;
00286             while (phase != null) {
00287               int size = phase.nodeList.size();
00288               for (int i=0; i<size; i++)  {
00289                 DependNode node = (DependNode) phase.nodeList.get(i);
00290                 if (node.nodeName.equals(nodeName)) {
00291                   phase.nodeList.remove(i);
00292                   return true;
00293                 }
00294               }
00295               phase = phase.nextPhase;
00296             }
00297             return false;
00298   }
00299 
00300 }
00301 
00302 

Generated on Mon Jan 11 21:19:14 2010 for OpenMobileIS by  doxygen 1.5.4