Coverage Report - org.argouml.profile.internal.DependencyResolver
 
Classes in this File Line Coverage Branch Coverage Complexity
DependencyResolver
12%
5/39
0%
0/18
3.2
 
 1  
 /* $Id: DependencyResolver.java 18318 2010-04-20 21:52:26Z euluis $
 2  
  *****************************************************************************
 3  
  * Copyright (c) 2010 Contributors - see below
 4  
  * All rights reserved. This program and the accompanying materials
 5  
  * are made available under the terms of the Eclipse Public License v1.0
 6  
  * which accompanies this distribution, and is available at
 7  
  * http://www.eclipse.org/legal/epl-v10.html
 8  
  *
 9  
  * Contributors:
 10  
  *    Luis Sergio Oliveira (euluis)
 11  
  *****************************************************************************
 12  
  */
 13  
 
 14  
 package org.argouml.profile.internal;
 15  
 
 16  
 import java.util.Collections;
 17  
 import java.util.HashSet;
 18  
 import java.util.Collection;
 19  
 
 20  
 import org.apache.log4j.Logger;
 21  
 
 22  
 /**
 23  
  * A dependency resolver for items of type T. It implements a state-full
 24  
  * dependency resolution algorithm.
 25  
  *
 26  
  * @author Luis Sergio Oliveira (euluis)
 27  
  * @param <T> the type of items for which dependencies will be resolved.
 28  
  */
 29  
 class DependencyResolver<T> {
 30  
     
 31  900
     private static final Logger LOG = Logger.getLogger(
 32  
             DependencyResolver.class);
 33  
 
 34  
     private DependencyChecker<T> checker;
 35  
     /**
 36  
      * WARNING: only to be used from outside classes by tests.
 37  
      * This is the state-full part of the algorithm, storing the unresolved
 38  
      * items between resolve methods calls.
 39  
      */
 40  
     Collection<T> unresolvedItems;
 41  
 
 42  
     /**
 43  
      * Create a dependency resolver and initialize it with the associated
 44  
      * dependency checker.
 45  
      *
 46  
      * @param checker the object that will be invoked to check if for a certain
 47  
      *                item all dependencies are resolved.
 48  
      */
 49  900
     DependencyResolver(DependencyChecker<T> checker) {
 50  900
         this.checker = checker;
 51  900
         unresolvedItems = new HashSet<T>();
 52  900
     }
 53  
 
 54  
     /**
 55  
      * Attempt to resolve the dependencies of the items already handed over to
 56  
      * the resolver instance.
 57  
      */
 58  
     void resolve() {
 59  0
         if (unresolvedItems.isEmpty()) {
 60  0
             return;
 61  
         }
 62  0
         final Collection<T> items = Collections.emptyList();
 63  0
         resolve(items);
 64  0
     }
 65  
 
 66  
     /**
 67  
      * Attempt to resolve the dependencies of the items already handed over to
 68  
      * the resolver instance and the additional items handed over now.
 69  
      *
 70  
      * @param items additional items to resolve.
 71  
      */
 72  
     void resolve(Collection<T> items) {
 73  0
         if (unresolvedItems.isEmpty() && items.isEmpty()) {
 74  0
             return;
 75  
         }
 76  0
         Collection<T> allUnresolvedItems = new HashSet<T>();
 77  0
         allUnresolvedItems.addAll(items);
 78  0
         allUnresolvedItems.addAll(unresolvedItems);
 79  0
         if (LOG.isDebugEnabled()) {
 80  0
             LOG.debug(items2Msg("Attempt to resolve the following items:",
 81  
                 allUnresolvedItems));
 82  
         }
 83  0
         Collection<T> resolved = internalResolve(allUnresolvedItems);
 84  0
         allUnresolvedItems.removeAll(resolved);
 85  0
         unresolvedItems.clear();
 86  0
         unresolvedItems.addAll(allUnresolvedItems);
 87  0
         if (!unresolvedItems.isEmpty()) {
 88  0
             LOG.warn(items2Msg(
 89  
                 "The following items were left unresolved after attempt:\n",
 90  
                 unresolvedItems));
 91  
         }
 92  0
     }
 93  
 
 94  
     private String items2Msg(String preface, Collection<T> items) {
 95  0
         StringBuffer msg = new StringBuffer(preface);
 96  0
         for (T item : items) {
 97  0
             msg.append("\t");
 98  0
             msg.append(item.toString());
 99  0
             msg.append("\n");
 100  
         }
 101  0
         return msg.toString();
 102  
     }
 103  
 
 104  
     /**
 105  
      * Recursively resolve all dependencies. Stops when an iteration through
 106  
      * all unresolved items didn't manage to resolve any.
 107  
      * 
 108  
      * @param items items to resolve.
 109  
      * @return the items that were resolved.
 110  
      */
 111  
     private Collection<T> internalResolve(Collection<T> items) {
 112  0
         Collection<T> resolved = new HashSet<T>();
 113  0
         for (T item : items) {
 114  0
             if (checker.check(item)) {
 115  0
                 resolved.add(item);
 116  
             }
 117  
         }
 118  0
         HashSet<T> toResolveItems = new HashSet<T>(items);
 119  0
         toResolveItems.removeAll(resolved);
 120  0
         if (!resolved.isEmpty()) {
 121  0
             resolved.addAll(internalResolve(toResolveItems));
 122  
         }
 123  0
         return resolved;
 124  
     }
 125  
 }