001: /*
002: * Copyright (c) 2001-2007, Jean Tessier
003: * All rights reserved.
004: *
005: * Redistribution and use in source and binary forms, with or without
006: * modification, are permitted provided that the following conditions
007: * are met:
008: *
009: * * Redistributions of source code must retain the above copyright
010: * notice, this list of conditions and the following disclaimer.
011: *
012: * * Redistributions in binary form must reproduce the above copyright
013: * notice, this list of conditions and the following disclaimer in the
014: * documentation and/or other materials provided with the distribution.
015: *
016: * * Neither the name of Jean Tessier nor the names of his contributors
017: * may be used to endorse or promote products derived from this software
018: * without specific prior written permission.
019: *
020: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
021: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
022: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
023: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
024: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
027: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
028: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
029: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
030: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031: */
032:
033: package com.jeantessier.dependency;
034:
035: import java.util.*;
036:
037: public class TransitiveClosureEngine {
038: private NodeFactory factory;
039: private ClosureLayerSelector layerSelector;
040: private ClosureStopSelector stopSelector;
041:
042: private Collection<Node> coverage = new HashSet<Node>();
043: private LinkedList<Collection<? extends Node>> selections = new LinkedList<Collection<? extends Node>>();
044: private LinkedList<Collection<? extends Node>> layers = new LinkedList<Collection<? extends Node>>();
045:
046: public TransitiveClosureEngine(Collection<? extends Node> packages,
047: SelectionCriteria startCriteria,
048: SelectionCriteria stopCriteria,
049: ClosureLayerSelector layerSelector) {
050: this (new NodeFactory(), packages, startCriteria, stopCriteria,
051: layerSelector);
052: }
053:
054: public TransitiveClosureEngine(NodeFactory factory,
055: Collection<? extends Node> packages,
056: SelectionCriteria startCriteria,
057: SelectionCriteria stopCriteria,
058: ClosureLayerSelector layerSelector) {
059: this .factory = factory;
060:
061: this .layerSelector = layerSelector;
062: this .layerSelector.setFactory(factory);
063: this .layerSelector.setCoverage(coverage);
064:
065: this .stopSelector = new ClosureStopSelector(stopCriteria);
066:
067: init(packages, startCriteria);
068: }
069:
070: private void init(Collection<? extends Node> packages,
071: SelectionCriteria startCriteria) {
072: ClosureStartSelector startSelector = new ClosureStartSelector(
073: factory, startCriteria);
074: startSelector.traverseNodes(packages);
075: stopSelector.traverseNodes(startSelector.getCopiedNodes());
076: gatherResults(startSelector);
077: }
078:
079: public NodeFactory getFactory() {
080: return factory;
081: }
082:
083: public int getNbLayers() {
084: return layers.size();
085: }
086:
087: public Collection getLayer(int i) {
088: return (Collection) layers.get(i);
089: }
090:
091: public void computeAllLayers() {
092: while (!stopSelector.isDone()) {
093: computeNextLayer();
094: }
095: }
096:
097: public void computeLayers(long nbLayers) {
098: for (long i = 0; !stopSelector.isDone() && i < nbLayers; i++) {
099: computeNextLayer();
100: }
101: }
102:
103: public void computeNextLayer() {
104: if (!stopSelector.isDone()) {
105: layerSelector.reset();
106: layerSelector.traverseNodes(selections.getLast());
107:
108: stopSelector.traverseNodes(layerSelector.getCopiedNodes());
109: if (!layerSelector.getCopiedNodes().isEmpty()) {
110: gatherResults(layerSelector);
111: }
112: }
113: }
114:
115: private void gatherResults(ClosureSelector selector) {
116: coverage.addAll(selector.getSelectedNodes());
117: selections.add(selector.getSelectedNodes());
118: layers.add(selector.getCopiedNodes());
119: }
120: }
|