001: /*
002: * @(#)DependenceAnalyzer.java 1.14 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: package dependenceAnalyzer;
029:
030: import util.ClassFileFinder;
031: import util.Set;
032: import java.util.Enumeration;
033: import java.util.Dictionary;
034: import java.util.Hashtable;
035:
036: /*
037: * A DependenceAnalyzer is the engine that actually does the work
038: * and is the root of a dependence graph. You will subclass this,
039: * depending on the level of analysis you want, but I believe
040: * that the functions provided here are common.
041: */
042: public abstract class DependenceAnalyzer {
043:
044: /*
045: * This analyzer maintains a name-to-node dictionary of
046: * its graph. This lets you lookup nodes by name. It will
047: * return null if the named entity is not in the graph.
048: */
049: public abstract DependenceNode nodeByName(Object name);
050:
051: /*
052: * Way(s) to access the whole graph.
053: */
054: public abstract Enumeration allNodes();
055:
056: // too hard for now.
057: //public Enumeration unanalyzedNodes();
058: //public Enumeration errorNodes();
059:
060: /*
061: * To conditionally add a node to the graph. It is not
062: * an error to add something that's already in the graph.
063: * The return value is a DependenceNode. It may be
064: * in any state, but if it was not in the graph previous to
065: * this call, it will certainly be DependenceNode.UNANALYZED.
066: * In other words, this call doesn't cause analysis.
067: */
068: public abstract DependenceNode addNodeByName(Object name);
069:
070: /*
071: * To cause the state of a node to move from UNANALYZED,
072: * one hopes to ANALYZED, but perhaps to ERROR.
073: * Return value is the new state of the node.
074: */
075: public abstract int analyzeDependences(DependenceNode node);
076:
077: /*
078: * To complete analysis of the whole graph. Return value
079: * is true if all nodes in the graph end in state
080: * ANALYZED, else false.
081: * Any nodes not ANALYZED will be in state ERROR.
082: */
083: public boolean analyzeAllDependences() {
084: Enumeration nodeList;
085: boolean changed;
086: boolean succeed = true;
087: do {
088: changed = false;
089: nodeList = allNodes();
090: while (nodeList.hasMoreElements()) {
091: DependenceNode dep = (DependenceNode) (nodeList
092: .nextElement());
093: if (dep.state() == DependenceNode.UNANALYZED) {
094: analyzeDependences(dep);
095: changed = true;
096: }
097: if (dep.state() == DependenceNode.ERROR)
098: succeed = false;
099: }
100: } while (changed);
101: return succeed;
102: }
103: }
|