001: /*
002: * Hammurapi
003: * Automated Java code review system.
004: * Copyright (C) 2004 Pavel Vlasov
005: *
006: * This program is free software; you can redistribute it and/or modify
007: * it under the terms of the GNU General Public License as published by
008: * the Free Software Foundation; either version 2 of the License, or
009: * (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: *
020: * URL: http://www.hammurapi.org
021: * e-Mail: vlasov@pavelvlasov.com
022:
023: */
024: package org.hammurapi.inspectors;
025:
026: import org.hammurapi.InspectorBase;
027:
028: import com.pavelvlasov.config.ConfigurationException;
029: import com.pavelvlasov.config.Parameterizable;
030: import com.pavelvlasov.jsel.Operation;
031:
032: /**
033: * Cyclomatic complexity exceeds specified maximum.
034: * @author Pavel Vlasov
035: * @version $Revision: 1.5 $
036: */
037: public class CyclomaticComplexityRule extends InspectorBase implements
038: Parameterizable {
039: /**
040: * Stores the setting form the configuration for the maximum allowed
041: * complexity for an operation.
042: */
043: private Integer operationMaxComplexity;
044: /**
045: * Stores the setting form the configuration for the maximum allowed
046: * complexity for a class.
047: */
048: private Integer classMaxComplexity;
049:
050: //Anu 24th May 05 :added for setting the upper limit for ER-011(Yellow) inspector
051: /**
052: * Stores the setting form the configuration for the maximum allowed
053: * complexity for the operation ER-011 (Red) .This is the upper range check for
054: * ER-011(Yellow).
055: */
056:
057: private Integer operationMaxRedComplexity;
058: /**
059: * Stores the setting form the configuration for the maximum allowed
060: * complexity for a class ER-011 (Red) .This is the upper range check for
061: * ER-011(Yellow).
062: */
063: private Integer classMaxRedComplexity;
064:
065: //Anu 24th May 05 :End
066: /**
067: * Reviews the methods and calculates their complexity.
068: *
069: * @param operation the method to be reviewed.
070: */
071: public void visit(Operation operation) {
072: int complexity = operation.getComplexity();
073: context
074: .addMetric(operation, "Operation complexity",
075: complexity);
076: //Anu 24th May 05 :added check for the upper limit for ER-011(Yellow) inspector
077: if (operationMaxRedComplexity != null) {
078: if (operationMaxComplexity != null
079: && complexity > operationMaxComplexity.intValue()
080: && complexity < operationMaxRedComplexity
081: .intValue()) {
082: context.reportViolation(operation,
083: new Object[] { operationMaxComplexity,
084: new Integer(complexity) });
085: }
086: } else {
087: if (operationMaxComplexity != null
088: && complexity > operationMaxComplexity.intValue()) {
089: context.reportViolation(operation,
090: new Object[] { operationMaxComplexity,
091: new Integer(complexity) });
092: }
093: }
094: }
095:
096: /**
097: * Reviews the class definition and calculates its complexity.
098: *
099: * @param clazz the class definition to be reviewed.
100: */
101: public void visit(com.pavelvlasov.jsel.Class clazz) {
102: int complexity = clazz.getComplexity();
103: context.addMetric(clazz, "Class complexity", complexity);
104: //Anu 24th May 05 :added check for the upper limit for ER-011(Yellow) inspector
105: if (classMaxRedComplexity != null) {
106: if (classMaxComplexity != null
107: && complexity > classMaxComplexity.intValue()
108: && complexity < classMaxRedComplexity.intValue()) {
109: context.reportViolation(clazz, new Object[] {
110: classMaxComplexity, new Integer(complexity) });
111: }
112: } else {
113: if (classMaxComplexity != null
114: && complexity > classMaxComplexity.intValue()) {
115: context.reportViolation(clazz, new Object[] {
116: classMaxComplexity, new Integer(complexity) });
117: }
118: }
119: }
120:
121: /**
122: * Configures the rule. Reads in the values of the parameters operation-max-complexity and
123: * class-max-complexity.
124: *
125: * @param name the name of the parameter being loaded from Hammurapi configuration
126: * @param value the value of the parameter being loaded from Hammurapi configuration
127: * @exception ConfigurationException in case of a not supported parameter
128: */
129: public boolean setParameter(String name, Object value)
130: throws ConfigurationException {
131: if ("operation-max-complexity".equals(name)) {
132: operationMaxComplexity = (Integer) value;
133: } else if ("class-max-complexity".equals(name)) {
134: classMaxComplexity = (Integer) value;
135: // Anu 24th May 05 :added check for the upper limit for ER-011(Yellow) inspector
136: } else if ("class-max-redcomplexity".equals(name)) {
137: classMaxRedComplexity = (Integer) value;
138: } else if ("operation-max-redcomplexity".equals(name)) {
139: operationMaxRedComplexity = (Integer) value;
140: } else {
141: throw new ConfigurationException("Parameter '" + name
142: + "' is not supported");
143: }
144: // Anu 24th May 05 :added check for the upper limit for ER-011(Yellow) inspector should
145: // be more than the max limit
146: if (operationMaxRedComplexity != null
147: && operationMaxComplexity != null) {
148: if (operationMaxRedComplexity.intValue() < operationMaxComplexity
149: .intValue()) {
150: throw new ConfigurationException(
151: "operationMaxRedComplexity should be higher than operationMaxComplexity");
152: }
153: }
154: if (classMaxRedComplexity != null && classMaxComplexity != null) {
155: if (classMaxRedComplexity.intValue() < classMaxComplexity
156: .intValue()) {
157: throw new ConfigurationException(
158: "classMaxRedComplexity should be higher than classMaxComplexity");
159: }
160: }
161: return true;
162: }
163:
164: /**
165: * Gives back the preconfigured values.
166: */
167: public String getConfigInfo() {
168: StringBuffer ret = new StringBuffer(
169: "Allowed cyclematic complexity:\n");
170: ret.append("operation: " + operationMaxComplexity + "\t");
171: ret.append("class: " + classMaxComplexity + "\n");
172: return ret.toString();
173: }
174: }
|