Clover coverage report - Code Coverage for hivemind release 1.0-beta-1
Coverage timestamp: Sat Jul 3 2004 09:41:37 EDT
file stats: LOC: 390   Methods: 15
NCLOC: 272   Classes: 2
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
 
 Source file Conditionals Statements Methods TOTAL
Orderer.java 100% 95% 86.7% 95.4%
coverage coverage
 1   
 //  Copyright 2004 The Apache Software Foundation
 2   
 //
 3   
 // Licensed under the Apache License, Version 2.0 (the "License");
 4   
 // you may not use this file except in compliance with the License.
 5   
 // You may obtain a copy of the License at
 6   
 //
 7   
 //     http://www.apache.org/licenses/LICENSE-2.0
 8   
 //
 9   
 // Unless required by applicable law or agreed to in writing, software
 10   
 // distributed under the License is distributed on an "AS IS" BASIS,
 11   
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12   
 // See the License for the specific language governing permissions and
 13   
 // limitations under the License.
 14   
 
 15   
 package org.apache.hivemind.order;
 16   
 
 17   
 import java.util.ArrayList;
 18   
 import java.util.Collections;
 19   
 import java.util.HashMap;
 20   
 import java.util.Iterator;
 21   
 import java.util.List;
 22   
 import java.util.Map;
 23   
 
 24   
 import org.apache.commons.logging.Log;
 25   
 import org.apache.commons.logging.LogFactory;
 26   
 import org.apache.hivemind.ErrorHandler;
 27   
 import org.apache.hivemind.HiveMind;
 28   
 import org.apache.hivemind.util.StringUtils;
 29   
 
 30   
 import com.werken.werkz.Action;
 31   
 import com.werken.werkz.CyclicGoalChainException;
 32   
 import com.werken.werkz.DefaultAction;
 33   
 import com.werken.werkz.Goal;
 34   
 import com.werken.werkz.Session;
 35   
 import com.werken.werkz.WerkzProject;
 36   
 
 37   
 /**
 38   
  * Used to order objects into an "execution" order.  Each object must have a name.
 39   
  * It may specify a list of pre-requisites and a list of post-requisites.
 40   
  *
 41   
  * @author Howard Lewis Ship
 42   
  */
 43   
 public class Orderer
 44   
 {
 45   
     private final Log _log;
 46   
     private final ErrorHandler _errorHandler;
 47   
     private final String _objectType;
 48   
     private List _orderingsList = null;
 49   
     private Map _orderingsMap = null;
 50   
     private List _orderedObjects;
 51   
     private Goal _leader;
 52   
     private Goal _trailer;
 53   
 
 54   
     /**
 55   
      * Creates an instance using <code>org.apache.hivemind.order.Orderer</code> as the Log.
 56   
      */
 57  10
     public Orderer(ErrorHandler errorHandler, String objectType)
 58   
     {
 59  10
         this(LogFactory.getLog(Orderer.class), errorHandler, objectType);
 60   
     }
 61   
 
 62   
     /**
 63   
      * Creates a new instance, but directs all debug and error logging output
 64   
      * to the provided log.
 65   
      * 
 66   
      * @param log Used for logging any errors
 67   
      * @param objectType user presentable name for the type of object to be ordered; used in some error messages
 68   
      */
 69  30
     public Orderer(Log log, ErrorHandler errorHandler, String objectType)
 70   
     {
 71  30
         _log = log;
 72  30
         _errorHandler = errorHandler;
 73  30
         _objectType = objectType;
 74   
 
 75  30
         HiveMind.checkNullParameter("log", log);
 76  30
         HiveMind.checkNullParameter("errorHandler", errorHandler);
 77  30
         HiveMind.checkNullParameter("objectType", objectType);
 78   
     }
 79   
 
 80   
     /**
 81   
      * Adds a new object.  All invocations of {@link #add(Object, String, String, String)}
 82   
      * should occur before invoking {@link #getOrderedObjects()}.
 83   
      * 
 84   
      * @param object an object to be sorted into order based on prereqs and postreqs
 85   
      * @param name a unique name for the 
 86   
      * @param prereqs a comma-separated list of the names of objects that should precede this
 87   
      * object in the list (or null)
 88   
      * @param postreqs a comma-separated list of the names of objects that should follow this
 89   
      * object in the list (or null)
 90   
      */
 91  74
     public void add(Object object, String name, String prereqs, String postreqs)
 92   
     {
 93  74
         if (_orderingsMap == null)
 94   
         {
 95  29
             _orderingsMap = new HashMap();
 96  29
             _orderingsList = new ArrayList();
 97   
         }
 98   
 
 99  74
         ObjectOrdering o = getOrderable(name);
 100   
 
 101  74
         if (o != null)
 102   
         {
 103  1
             _errorHandler.error(
 104   
                 _log,
 105   
                 OrdererMessages.duplicateName(_objectType, name, object, o.getObject()),
 106   
                 HiveMind.getLocation(object),
 107   
                 null);
 108   
 
 109  1
             return;
 110   
         }
 111   
 
 112  73
         o = new ObjectOrdering(object, name, prereqs, postreqs);
 113   
 
 114  73
         _orderingsMap.put(name, o);
 115  73
         _orderingsList.add(o);
 116   
     }
 117   
 
 118  78
     private ObjectOrdering getOrderable(String name)
 119   
     {
 120  78
         return (ObjectOrdering) _orderingsMap.get(name);
 121   
     }
 122   
 
 123   
     /**
 124   
      * Uses the information provided by {@link #add(Object, String, String, String)} to order
 125   
      * the objects into an appropriate order based on the pre- and post-reqts provided.
 126   
      * Errors such as cyclic dependencies or unrecognized names are logged and ignored.
 127   
      */
 128  30
     public List getOrderedObjects()
 129   
     {
 130  30
         if (_orderingsMap == null)
 131  1
             return Collections.EMPTY_LIST;
 132   
 
 133  29
         try
 134   
         {
 135  29
             _orderedObjects = new ArrayList(_orderingsMap.size());
 136   
 
 137  29
             runGoals();
 138   
 
 139  29
             return _orderedObjects;
 140   
         }
 141   
         finally
 142   
         {
 143  29
             _orderedObjects = null;
 144  29
             _leader = null;
 145  29
             _trailer = null;
 146   
         }
 147   
     }
 148   
 
 149   
     private static class NullAction extends DefaultAction
 150   
     {
 151   
 
 152  52
         public void performAction() throws Exception
 153   
         {
 154   
 
 155   
         }
 156   
 
 157  0
         public void performAction(Session arg0) throws Exception
 158   
         {
 159   
 
 160   
         }
 161   
 
 162   
     }
 163   
 
 164  29
     private void runGoals()
 165   
     {
 166  29
         WerkzProject p = new WerkzProject();
 167   
 
 168  29
         addGoals(p);
 169   
 
 170  29
         if (_leader == null)
 171   
         {
 172  25
             _leader = new Goal("*-leader-*", new NullAction());
 173  25
             p.addGoal(_leader);
 174   
         }
 175   
 
 176  29
         if (_trailer == null)
 177   
         {
 178  27
             _trailer = new Goal("*-trailer-*", new NullAction());
 179   
 
 180  27
             p.addGoal(_trailer);
 181   
         }
 182   
 
 183  29
         addDependencies(p);
 184   
 
 185  29
         try
 186   
         {
 187  29
             _trailer.attain(new Session());
 188   
         }
 189   
         catch (Exception ex)
 190   
         {
 191  0
             _errorHandler.error(_log, OrdererMessages.exception(_objectType, ex), null, ex);
 192   
         }
 193   
     }
 194   
 
 195  29
     private void addGoals(WerkzProject project)
 196   
     {
 197  29
         Iterator i = _orderingsList.iterator();
 198   
 
 199  29
         while (i.hasNext())
 200   
         {
 201  73
             final ObjectOrdering o = (ObjectOrdering) i.next();
 202   
 
 203  73
             Action a = new DefaultAction()
 204   
             {
 205  73
                 public void performAction()
 206   
                 {
 207  73
                     _orderedObjects.add(o.getObject());
 208   
                 }
 209   
 
 210  0
                 public void performAction(Session session)
 211   
                 {
 212  0
                     performAction();
 213   
                 }
 214   
             };
 215   
 
 216  73
             Goal goal = new Goal(o.getName(), a);
 217   
 
 218  73
             project.addGoal(goal);
 219   
 
 220  73
             if ("*".equals(o.getPostreqs()))
 221   
             {
 222  5
                 if (_leader == null)
 223  4
                     _leader = goal;
 224   
                 else
 225   
                 {
 226  1
                     _errorHandler.error(
 227   
                         _log,
 228   
                         OrdererMessages.dupeLeader(_objectType, o, getOrderable(_leader.getName())),
 229   
                         HiveMind.getLocation(o.getObject()),
 230   
                         null);
 231   
                 }
 232   
             }
 233   
 
 234  73
             if ("*".equals(o.getPrereqs()))
 235   
             {
 236  3
                 if (_trailer == null)
 237  2
                     _trailer = goal;
 238   
                 else
 239   
                 {
 240  1
                     _errorHandler.error(
 241   
                         _log,
 242   
                         OrdererMessages.dupeTrailer(
 243   
                             _objectType,
 244   
                             o,
 245   
                             getOrderable(_trailer.getName())),
 246   
                         HiveMind.getLocation(o.getObject()),
 247   
                         null);
 248   
                 }
 249   
             }
 250   
 
 251   
         }
 252   
     }
 253   
 
 254  29
     private void addDependencies(WerkzProject project)
 255   
     {
 256  29
         Iterator i = _orderingsList.iterator();
 257   
 
 258  29
         while (i.hasNext())
 259   
         {
 260  73
             ObjectOrdering o = (ObjectOrdering) i.next();
 261  73
             String name = o.getName();
 262   
 
 263  73
             Goal goal = project.getGoal(name);
 264   
 
 265  73
             addDependencies(project, goal, o);
 266   
         }
 267   
     }
 268   
 
 269  73
     private void addDependencies(WerkzProject project, Goal goal, ObjectOrdering orderable)
 270   
     {
 271   
 
 272  73
         addPrecursors(project, orderable, goal);
 273  73
         addPostcursors(project, orderable, goal);
 274   
 
 275  73
         try
 276   
         {
 277  73
             if (goal != _leader)
 278  69
                 _leader.addPostcursor(goal);
 279   
 
 280  73
             if (goal != _trailer)
 281  71
                 _trailer.addPrecursor(goal);
 282   
         }
 283   
         catch (CyclicGoalChainException ex)
 284   
         {
 285   
             // This code is unreachable ... but nonetheless.
 286   
 
 287  0
             String name = goal.getName();
 288  0
             ObjectOrdering trigger = getOrderable(name);
 289   
 
 290  0
             _errorHandler.error(
 291   
                 _log,
 292   
                 OrdererMessages.dependencyCycle(_objectType, trigger, ex),
 293   
                 HiveMind.getLocation(orderable.getObject()),
 294   
                 ex);
 295   
         }
 296   
     }
 297   
 
 298  73
     private void addPrecursors(WerkzProject project, ObjectOrdering ordering, Goal goal)
 299   
     {
 300  73
         String prereqs = ordering.getPrereqs();
 301   
 
 302  73
         if ("*".equals(prereqs))
 303  3
             return;
 304   
 
 305  70
         String[] names = StringUtils.split(prereqs);
 306   
 
 307  70
         for (int i = 0; i < names.length; i++)
 308   
         {
 309  14
             String prename = names[i];
 310   
 
 311  14
             Goal pregoal = project.getGoal(prename);
 312   
 
 313  14
             if (pregoal == null)
 314   
             {
 315  1
                 _errorHandler.error(
 316   
                     _log,
 317   
                     OrdererMessages.badDependency(_objectType, prename, ordering),
 318   
                     HiveMind.getLocation(ordering.getObject()),
 319   
                     null);
 320  1
                 continue;
 321   
             }
 322   
 
 323  13
             try
 324   
             {
 325  13
                 goal.addPrecursor(pregoal);
 326   
             }
 327   
             catch (CyclicGoalChainException ex)
 328   
             {
 329  1
                 String name = goal.getName();
 330  1
                 ObjectOrdering trigger = getOrderable(name);
 331   
 
 332  1
                 _errorHandler.error(
 333   
                     _log,
 334   
                     OrdererMessages.dependencyCycle(_objectType, trigger, ex),
 335   
                     HiveMind.getLocation(trigger.getObject()),
 336   
                     ex);
 337   
             }
 338   
 
 339   
         }
 340   
     }
 341   
 
 342  73
     private void addPostcursors(WerkzProject project, ObjectOrdering ordering, Goal goal)
 343   
     {
 344   
 
 345  73
         String postreqs = ordering.getPostreqs();
 346   
 
 347  73
         if ("*".equals(postreqs))
 348  5
             return;
 349   
 
 350  68
         String[] names = StringUtils.split(postreqs);
 351   
 
 352  68
         for (int i = 0; i < names.length; i++)
 353   
         {
 354  24
             String postname = names[i];
 355   
 
 356  24
             Goal postgoal = project.getGoal(postname);
 357   
 
 358  24
             if (postgoal == null)
 359   
             {
 360  1
                 _errorHandler.error(
 361   
                     _log,
 362   
                     OrdererMessages.badDependency(_objectType, postname, ordering),
 363   
                     HiveMind.getLocation(ordering.getObject()),
 364   
                     null);
 365   
             }
 366   
             else
 367   
             {
 368   
 
 369  23
                 try
 370   
                 {
 371  23
                     goal.addPostcursor(postgoal);
 372   
                 }
 373   
                 catch (CyclicGoalChainException ex)
 374   
                 {
 375  1
                     String name = goal.getName();
 376  1
                     ObjectOrdering trigger = getOrderable(name);
 377   
 
 378  1
                     _errorHandler.error(
 379   
                         _log,
 380   
                         OrdererMessages.dependencyCycle(_objectType, trigger, ex),
 381   
                         HiveMind.getLocation(trigger.getObject()),
 382   
                         ex);
 383   
                 }
 384   
 
 385   
             }
 386   
         }
 387   
 
 388   
     }
 389   
 }
 390