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 org.hammurapi.InspectorBase;
026: import org.hammurapi.HammurapiException;
027:
028: import com.pavelvlasov.jsel.Constructor;
029: import com.pavelvlasov.jsel.TypeDefinition;
030: import com.pavelvlasov.jsel.statements.Statement;
031: import com.pavelvlasov.jsel.statements.SuperConstructorCall;
032: import com.pavelvlasov.util.AccumulatingVisitorExceptionSink;
033: import com.pavelvlasov.util.DispatchingVisitor;
034:
035: /**
036: * @author Janos Czako
037: *
038: * <description>Unnecessary constructor detects when a constructor is not
039: * necessary; i.e., when there's only one constructor, it's public, has an
040: * empty body, and takes no arguments. (PMD) </description>
041: *
042: * Example:
043: * public DaoX(){
044: super();
045: }
046:
047: */
048: public class UnnecessaryConstructorRule extends InspectorBase {
049:
050: /**
051: * The chained visitor class which searches after constructor definitions.
052: */
053: public static class ConstructorSnooper {
054:
055: /**
056: * The list of the constructor definitions found.
057: */
058: java.util.List constList = new java.util.ArrayList();
059:
060: /**
061: * Reviews the constructor definitions and collects them.
062: *
063: * @param constructor the constructor definition
064: */
065: public void visit(Constructor constructor) {
066: constList.add(constructor);
067: }
068: }
069:
070: /**
071: * The error text for exceptions in the chained visitor.
072: */
073: private static final String CHAINED_ERRS = "There have been exceptions (see above)";
074:
075: /**
076: * Reviews the type definition if it violates against the rule.
077: *
078: * @param element the type definition to be reviewed.
079: * @throws HammurapiException in case of any exception in the chained visitor
080: */
081: public void visit(TypeDefinition element) throws HammurapiException {
082: AccumulatingVisitorExceptionSink es = new AccumulatingVisitorExceptionSink();
083: ConstructorSnooper rs = new ConstructorSnooper();
084: element.accept(new DispatchingVisitor(rs, es));
085:
086: if (rs.constList.size() == 1) {
087: Constructor constructor = (Constructor) rs.constList.get(0);
088:
089: checkConstructor(constructor);
090: }
091:
092: if (!es.getExceptions().isEmpty()) {
093: es.dump();
094: throw new HammurapiException(CHAINED_ERRS);
095: }
096: }
097:
098: /**
099: * "public" modifier of the constructor
100: */
101: private static final String PUBLIC = "public";
102:
103: /**
104: * Checks if the constructor violates against the rule.
105: */
106: private void checkConstructor(Constructor constructor) {
107: if (constructor.getModifiers().contains(PUBLIC)
108: && constructor.getParameters().size() == 0) {
109:
110: if (isEmpty(constructor.getCompoundStatement())) {
111: context.reportViolation(constructor);
112: } else {
113: java.util.Iterator statements = constructor
114: .getCompoundStatement().getStatements()
115: .iterator();
116: int cntr = 0;
117: while (statements.hasNext()) {
118: Statement statement = (Statement) statements.next();
119: if (!(statement instanceof SuperConstructorCall)) {
120: cntr++;
121: }
122: }
123: if (cntr == 0) {
124: context.reportViolation(constructor);
125: }
126: }
127: }
128: }
129: }
|