001: /*
002: * Hammurapi
003: * Automated Java code review system.
004: * Copyright (C) 2004 Hammurapi Group
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: support@hammurapi.biz
022: */
023: package org.hammurapi.inspectors;
024:
025: import java.util.Iterator;
026:
027: import org.hammurapi.InspectorBase;
028:
029: import com.pavelvlasov.config.ConfigurationException;
030: import com.pavelvlasov.config.Parameterizable;
031: import com.pavelvlasov.jsel.Initializer;
032: import com.pavelvlasov.jsel.JselException;
033: import com.pavelvlasov.jsel.Repository;
034: import com.pavelvlasov.jsel.VariableDefinition;
035: import com.pavelvlasov.jsel.expressions.Expression;
036: import com.pavelvlasov.jsel.expressions.MethodCall;
037:
038: /**
039: * ER-066 Unify logging strategy - define individual logger for class
040: *
041: * @author Pavel Vlasov
042: * @version $Revision: 1.4 $
043: */
044: public class DefineLoggerForClassRule extends InspectorBase implements
045: Parameterizable {
046:
047: /**
048: * Reviews the type definition and cheks if it has a logger field.
049: *
050: * @param type
051: * the type definition to be reviewed.
052: */
053: public void visit(com.pavelvlasov.jsel.Class clazz) {
054: if (loggerClassName != null) {
055: Repository repository = clazz.getCompilationUnit()
056: .getPackage().getRepository();
057: try {
058: Class loggerClass = repository
059: .loadClass(loggerClassName);
060: Iterator it = clazz.getFields().iterator();
061: while (it.hasNext()) {
062: Object field = it.next();
063: if (field instanceof VariableDefinition) {
064: VariableDefinition variableDefinition = (VariableDefinition) field;
065: try {
066: if (variableDefinition
067: .getTypeSpecification().getType()
068: .isKindOf(loggerClassName)) {
069: context
070: .waive(variableDefinition,
071: "AvoidHidingInheritedInstanceFields");
072:
073: if (!("logger"
074: .equals(variableDefinition
075: .getName()) || "LOGGER"
076: .equals(variableDefinition
077: .getName()))) {
078: // TODO [0329] Move string to keyed message to descriptor
079: context
080: .reportViolation(
081: variableDefinition,
082: "Use unified name 'LOGGER' for loggers");
083: }
084:
085: if (!variableDefinition.getModifiers()
086: .contains("static")) {
087: // TODO [0329] Move string to keyed message to descriptor
088: context.reportViolation(
089: variableDefinition,
090: "Logger must be static");
091: }
092:
093: if (!variableDefinition.getModifiers()
094: .contains("private")) {
095: // TODO [0329] Move string to keyed message to descriptor
096: context.reportViolation(
097: variableDefinition,
098: "Logger must be private");
099: }
100:
101: if (!variableDefinition.getModifiers()
102: .contains("final")) {
103: // TODO [0329] Move string to keyed message to descriptor
104: context.reportViolation(
105: variableDefinition,
106: "Logger must be final");
107: }
108:
109: Initializer initializer = variableDefinition
110: .getInitializer();
111: if (initializer == null) {
112: context.reportViolation(
113: variableDefinition,
114: "Logger not initialized");
115: } else {
116: if (initializer instanceof MethodCall) {
117: MethodCall mc = (MethodCall) initializer;
118: if (mc.getParameters().size() == 1) {
119: Expression expr = (Expression) mc
120: .getParameters()
121: .get(0);
122: if ("java.lang.Class"
123: .equals(expr
124: .getTypeSpecification()
125: .getType()
126: .getName())) {
127: String paramTypeName = expr
128: .toString();
129: String classType = clazz
130: .getFcn()
131: + ".class";
132: if (!paramTypeName
133: .equals(classType)
134: && !classType
135: .endsWith("."
136: + paramTypeName)) {
137:
138: context
139: .reportViolation(
140: variableDefinition,
141: "Parameter is not correct");
142: }
143: }
144: }
145: }
146: }
147: return;
148: }
149: } catch (JselException e) {
150: context.warn(variableDefinition, e);
151: }
152: }
153: }
154: context.reportViolation(clazz);
155: } catch (ClassNotFoundException e) {
156: context.warn(clazz, e);
157: }
158: }
159: }
160:
161: /**
162: * The fully quilified name of the Logger class.
163: */
164: private String loggerClassName;
165:
166: /**
167: * Configures rule. Reads in the values of the parameter logger-class-name
168: *
169: * @param name
170: * the name of the parameter being loaded from Hammurapi
171: * configuration
172: * @param value
173: * the value of the parameter being loaded from Hammurapi
174: * configuration
175: * @exception ConfigurationException
176: * in case of a not supported parameter
177: */
178: public boolean setParameter(String name, Object value)
179: throws ConfigurationException {
180: if ("logger-class-name".equals(name)) {
181: loggerClassName = value.toString();
182: return true;
183: }
184:
185: throw new ConfigurationException("Parameter " + name
186: + " is not supported.");
187: }
188:
189: /**
190: * Gives back the preconfigured values.
191: */
192: public String getConfigInfo() {
193: StringBuffer ret = new StringBuffer("Allowed logger class:\n");
194: ret.append("logger-class-name: " + loggerClassName + "\n");
195: return ret.toString();
196: }
197: }
|