001/* A base class for analyses on graphs. 002 003 Copyright (c) 2002-2014 The University of Maryland. All rights reserved. 004 Permission is hereby granted, without written agreement and without 005 license or royalty fees, to use, copy, modify, and distribute this 006 software and its documentation for any purpose, provided that the above 007 copyright notice and the following two paragraphs appear in all copies 008 of this software. 009 010 IN NO EVENT SHALL THE UNIVERSITY OF MARYLAND BE LIABLE TO ANY PARTY 011 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 012 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 013 THE UNIVERSITY OF MARYLAND HAS BEEN ADVISED OF THE POSSIBILITY OF 014 SUCH DAMAGE. 015 016 THE UNIVERSITY OF MARYLAND SPECIFICALLY DISCLAIMS ANY WARRANTIES, 017 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 018 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 019 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 020 MARYLAND HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 021 ENHANCEMENTS, OR MODIFICATIONS. 022 023 024 */ 025package ptolemy.graph.analysis; 026 027import ptolemy.graph.Graph; 028import ptolemy.graph.analysis.analyzer.Analyzer; 029import ptolemy.graph.analysis.analyzer.GraphAnalyzer; 030import ptolemy.graph.analysis.strategy.CachedStrategy; 031 032/////////////////////////////////////////////////////////////////// 033//// Analysis 034 035/** 036 A base class for analyses on graphs. 037 <p> 038 The organization of the package follows: 039 <p> 040 Classes in ptolemy.graph.analysis consists of different wrappers in 041 which a client can plug a requested strategy/algorithm for an analysis. 042 Strategies for a given analysis implement the same interface defined 043 in ptolemy.graph.analysis.analyzer. 044 Therefore from now on we will use the name analyzer for all the strategies 045 that implement the same interface and therefore solve the same problem. 046 Analysis classes access the plugged-in strategy class through these interfaces. 047 <p> 048 In the base class methods are provided in order to dynamically change the 049 analyzer of the current analysis and also to check if a given analyzer is 050 applicable to the given analysis. 051 <p> 052 Analyzers that can be used in these analyses are a specialized version of 053 analyzers called {@link ptolemy.graph.analysis.analyzer.GraphAnalyzer}. 054 <p> 055 Classes in ptolemy.graph.analysis.analyzer are the interfaces for 056 different strategies(algorithms) used for the analysis. The strategies classes 057 are defined in ptolemy.graph.analysis.strategy 058 <p> 059 In addition, the analysis classes provide default constructors which use 060 predefined strategies for those clients who do not want to deal with different 061 strategies. 062 Although this introduces some limitations imposed by the used strategy. The 063 documentation of such constructor will reflect the limitations, if any. 064 <p> 065 Finally, strategies can be instantiated and used independently. In this case 066 the client will lose the possibility of dynamically changing the analyzer for 067 the associated analysis, which would not exist at all, and there will be no 068 default constructor therefore the client need to be familiar with the strategy 069 that she/he is using. 070 071 @since Ptolemy II 2.0 072 @Pt.ProposedRating Red (shahrooz) 073 @Pt.AcceptedRating Red (ssb) 074 @author Shahrooz Shahparnia, Shuvra S. Bhattacharyya 075 @version $Id$ 076 */ 077public class Analysis { 078 /** Construct an analysis using a given analyzer. 079 * 080 * @param analyzer The given analyzer. 081 */ 082 public Analysis(GraphAnalyzer analyzer) { 083 _analyzer = analyzer; 084 085 // Maybe we may want to implement the Observer pattern instead of this. 086 graph().addAnalysis(this); 087 } 088 089 /////////////////////////////////////////////////////////////////// 090 //// public methods //// 091 092 /** Return the analyzer associated with this analysis class. 093 * 094 * @return Return the analyzer associated with this analysis class. 095 */ 096 public GraphAnalyzer analyzer() { 097 return _analyzer; 098 } 099 100 /** Change the analyzer associated with this analysis class to the given 101 * analyzer. 102 * 103 * @param analyzer The given analyzer. 104 * @exception InvalidAnalyzerException If the analyzer is not a valid 105 * analyzer for this analysis. 106 */ 107 public void changeAnalyzer(GraphAnalyzer analyzer) { 108 if (validAnalyzerInterface(analyzer)) { 109 if (analyzer instanceof CachedStrategy) { 110 if (graph() == analyzer().graph()) { 111 ((CachedStrategy) analyzer) 112 .setCachedResult((CachedStrategy) _analyzer); 113 } 114 } 115 116 _analyzer = analyzer; 117 } else { 118 throw new InvalidAnalyzerException( 119 "Invalid analyzer for the analysis:\n" + toString()); 120 } 121 } 122 123 /** The graph associated with the analysis. This association is made 124 * through the associated analyzer interface. 125 * 126 * @return Return the graph under analysis. 127 */ 128 public Graph graph() { 129 return _analyzer.graph(); 130 } 131 132 /** Return a description of the analysis and the associated analyzer. 133 * It should be overridden in derived classes to 134 * include details associated with the associated analysis/analyzer. 135 * 136 * @return A description of the analysis and the associated analyzer. 137 */ 138 @Override 139 public String toString() { 140 return "Analysis using the following analyzer:\n" 141 + _analyzer.toString(); 142 } 143 144 /** Return the validity of the associated analyzer. An analyzer is valid 145 * if the graph and the associated data is in a format suitable for the 146 * analyzer. 147 * 148 * @return Return the validity of the associated analyzer. 149 */ 150 public boolean valid() { 151 return _analyzer.valid(); 152 } 153 154 /** Check if a given analyzer is compatible with this analysis. 155 * In other words if it is possible to use it to compute the computation 156 * associated with this analysis. 157 * Derived classes should override this method to provide the valid type 158 * of analyzer that they need. 159 * 160 * @param analyzer The given analyzer. 161 * @return True if the given analyzer is valid for this analysis. 162 */ 163 public boolean validAnalyzerInterface(Analyzer analyzer) { 164 return analyzer instanceof GraphAnalyzer; 165 } 166 167 /////////////////////////////////////////////////////////////////// 168 //// private variables //// 169 // The analyzer that is used in the computation of this analysis. 170 private GraphAnalyzer _analyzer; 171}