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:
024: package org.hammurapi.results.persistent.jdbc;
025:
026: import java.lang.reflect.InvocationHandler;
027: import java.lang.reflect.Method;
028: import java.lang.reflect.Proxy;
029: import java.sql.PreparedStatement;
030: import java.sql.ResultSet;
031: import java.sql.SQLException;
032: import java.util.ArrayList;
033: import java.util.Collection;
034: import java.util.Date;
035: import java.util.HashMap;
036: import java.util.HashSet;
037: import java.util.Iterator;
038: import java.util.LinkedList;
039: import java.util.List;
040: import java.util.Map;
041: import java.util.Set;
042: import java.util.TreeMap;
043:
044: import org.hammurapi.HammurapiException;
045: import org.hammurapi.HammurapiMeasurement;
046: import org.hammurapi.HammurapiRuntimeException;
047: import org.hammurapi.Inspector;
048: import org.hammurapi.InspectorDescriptor;
049: import org.hammurapi.SimpleViolation;
050: import org.hammurapi.Violation;
051: import org.hammurapi.Waiver;
052: import org.hammurapi.WaiverSet;
053: import org.hammurapi.results.Annotation;
054: import org.hammurapi.results.InspectorSummary;
055: import org.hammurapi.results.persistent.jdbc.sql.AggregatedResultsInspectorViolations;
056: import org.hammurapi.results.persistent.jdbc.sql.AggregatedResultsMetric;
057: import org.hammurapi.results.persistent.jdbc.sql.AggregatedResultsMetricMeasurement;
058: import org.hammurapi.results.persistent.jdbc.sql.MeasurementImpl;
059: import org.hammurapi.results.persistent.jdbc.sql.ResultsEngine;
060: import org.hammurapi.results.persistent.jdbc.sql.ViolationImpl;
061: import org.hammurapi.results.persistent.jdbc.sql.ViolationJoined;
062:
063: import com.pavelvlasov.config.ConfigurationException;
064: import com.pavelvlasov.convert.Converter;
065: import com.pavelvlasov.metrics.Metric;
066: import com.pavelvlasov.persistence.PersistenceException;
067: import com.pavelvlasov.review.Signed;
068: import com.pavelvlasov.review.SimpleSourceMarker;
069: import com.pavelvlasov.review.SourceMarker;
070: import com.pavelvlasov.sql.Parameterizer;
071: import com.pavelvlasov.sql.RowProcessor;
072: import com.pavelvlasov.sql.RowProcessorEx;
073:
074: /**
075: *
076: * @author Pavel Vlasov
077: * @version $Revision: 1.19 $
078: */
079: public class AggregatedResults extends BasicResults implements
080: org.hammurapi.results.AggregatedResults {
081: protected static final byte VIOLATION = 0;
082: protected static final byte WAIVED_VIOLATION = 1;
083: protected static final byte WARNING = 2;
084:
085: AggregatedResults(WaiverSet waiverSet, ResultsFactory factory)
086: throws SQLException {
087: super (factory);
088: this .waiverSet = waiverSet;
089: id = factory.nextPK("RESULT");
090: factory.addToCache(this );
091: date = new Date();
092: factory
093: .getSQLProcessor()
094: .processUpdate(
095: "INSERT INTO RESULT (ID, TYPE, RESULT_DATE, CODEBASE) VALUES (?, ?, ?, 0)",
096: new Parameterizer() {
097: public void parameterize(
098: PreparedStatement ps)
099: throws SQLException {
100: ps.setInt(1, id);
101: ps.setString(2, AggregatedResults.this
102: .getClass().getName());
103: ps.setDate(3, new java.sql.Date(date
104: .getTime()));
105: }
106: });
107:
108: // Self parent for Oracle
109: factory.getSQLProcessor().processUpdate(
110: "INSERT INTO RESULT_NET (PARENT, CHILD) VALUES (?,?)",
111: new Parameterizer() {
112: public void parameterize(PreparedStatement ps)
113: throws SQLException {
114: ps.setInt(1, id);
115: ps.setInt(2, id);
116: }
117: });
118:
119: // Self kindred
120: factory
121: .getSQLProcessor()
122: .processUpdate(
123: "INSERT INTO KINDRED (ANCESTOR, DESCENDANT) VALUES (?, ?)",
124: new Parameterizer() {
125: public void parameterize(
126: PreparedStatement ps)
127: throws SQLException {
128: ps.setInt(1, id);
129: ps.setInt(2, id);
130: }
131: });
132: }
133:
134: /**
135: * @param id
136: * @param factory
137: * @throws SQLException
138: */
139: public AggregatedResults(int id, ResultsFactory factory)
140: throws SQLException {
141: super (id, factory);
142: }
143:
144: /**
145: * Add violation to severity summary
146: * @param violation
147: * @return Waiver
148: * @throws HammurapiException
149: */
150: public Waiver addViolation(final Violation violation)
151: throws HammurapiException {
152: final Waiver ret = waiverSet == null ? null : waiverSet
153: .requestWaiver(violation, false);
154: try {
155: ResultsEngine resultsEngine = factory.getResultsEngine();
156: if (ret == null) {
157: severitySummary = null;
158: InspectorDescriptor descriptor = insertViolation(
159: violation, VIOLATION, null);
160: ++violationsNumber;
161: resultsEngine.updateAggregatedResultsViolations(
162: violationsNumber, id);
163:
164: final int severity = descriptor.getSeverity()
165: .intValue();
166: if (maxSeverity == null
167: || maxSeverity.intValue() > severity) {
168: maxSeverity = new Integer(severity);
169: resultsEngine.updateAggregatedResultsMaxSeverity(
170: (short) severity, id);
171: }
172:
173: /**
174: * Violations with severity >=5 considered as hints.
175: */
176: if (severity > 0 && severity < 5) {
177: violationLevel += Math.pow(10, 1 - descriptor
178: .getSeverity().doubleValue());
179: resultsEngine.setViolationLevel(violationLevel,
180: getId());
181: }
182: } else {
183: ++waivedViolationsNumber;
184: resultsEngine.incWaivedViolations(getId());
185: }
186: } catch (SQLException e) {
187: throw new HammurapiException(e);
188: }
189: return ret;
190: }
191:
192: protected interface ViolationConfigurator {
193: void setViolationInfo(
194: org.hammurapi.results.persistent.jdbc.sql.Violation sqlViolation)
195: throws SQLException;
196: }
197:
198: protected InspectorDescriptor insertViolation(
199: final Violation violation, byte type,
200: ViolationConfigurator configurator) {
201: InspectorDescriptor descriptor = violation.getDescriptor();
202: try {
203: maybeInsertInspector(descriptor);
204:
205: ViolationImpl sqlViolation = new ViolationImpl(true);
206: sqlViolation.setId(factory.getSQLProcessor().nextPK(
207: "PRIMARY_KEY", "VIOLATION"));
208: sqlViolation.setViolationType(type);
209:
210: sqlViolation.setResultId(getId());
211: sqlViolation.setReportId(factory.getReportId());
212: if (descriptor != null) {
213: sqlViolation.setInspector(descriptor.getName()); // INSPECTOR
214: }
215:
216: String message = violation.getMessage();
217: if (message != null) {
218: sqlViolation.setMessageId(new Integer(factory
219: .addMessage(message))); // MESSAGE
220: }
221:
222: SourceMarker source = violation.getSource();
223: if (source != null) {
224: sqlViolation.setSourceId(source.getSourceId()); // SOURCE
225: sqlViolation.setLine(source.getLine()); // LINE
226: sqlViolation.setCol(source.getColumn()); // COL
227:
228: if (source instanceof Signed) {
229: String signature = ((Signed) source).getSignature();
230: if (signature != null
231: && signature.startsWith(source
232: .getSourceURL())) {
233: sqlViolation.setSignaturePostfix(signature
234: .substring(source.getSourceURL()
235: .length())); // SOURCE_SIGNATURE
236: }
237: }
238: }
239:
240: if (configurator != null) {
241: configurator.setViolationInfo(sqlViolation);
242: }
243:
244: factory.getResultsEngine().insertViolation(sqlViolation);
245: } catch (SQLException e1) {
246: throw new HammurapiRuntimeException(e1);
247: }
248: return descriptor;
249: }
250:
251: public void addWarning(Violation warning) {
252: insertViolation(warning, WARNING, null);
253: hasWarnings = true;
254: }
255:
256: private Set metricIds = new HashSet();
257:
258: private class MetricEntry {
259: int meid;
260: String name;
261:
262: public MetricEntry(int id, String name) {
263: super ();
264: this .meid = id;
265: this .name = name;
266: }
267:
268: public boolean equals(Object obj) {
269: return obj instanceof MetricEntry
270: && ((MetricEntry) obj).meid == meid
271: && ((MetricEntry) obj).name.equals(name);
272: }
273:
274: public int hashCode() {
275: return meid ^ name.hashCode();
276: }
277: }
278:
279: public void addMetric(final SourceMarker source, final String name,
280: final double value) {
281: try {
282: ResultsEngine engine = factory.getResultsEngine();
283: MetricEntry metricEntry = new MetricEntry(getId(), name);
284: if (!metricIds.contains(metricEntry)) {
285: org.hammurapi.results.persistent.jdbc.sql.Metric dbMetric = engine
286: .getMetric(getId(), name);
287: if (dbMetric == null) {
288: engine.insertMetric(getId(), name);
289: }
290: metricIds.add(metricEntry);
291: }
292:
293: MeasurementImpl measurement = new MeasurementImpl(true);
294: measurement.setId(factory.getSQLProcessor().nextPK(
295: "PRIMARY_KEY", "MEASUREMENT"));
296: if (source != null) {
297: measurement.setCol(source.getColumn());
298: measurement.setLine(source.getLine());
299: measurement.setSource(source.getSourceURL());
300: }
301: measurement.setResultId(getId());
302: measurement.setMeasurementValue(value);
303: measurement.setName(name);
304: engine.insertMeasurement(measurement);
305:
306: metrics = null;
307: } catch (SQLException e) {
308: throw new HammurapiRuntimeException(e);
309: }
310: }
311:
312: private Map metrics;
313:
314: public Map getMetrics() {
315: if (metrics == null) {
316: metrics = new TreeMap();
317: Iterator it = factory.getResultsEngine()
318: .getAggregatedResultsMetric(id).iterator();
319: while (it.hasNext()) {
320: final AggregatedResultsMetric arm = (AggregatedResultsMetric) it
321: .next();
322: metrics.put(arm.getName(), new Metric() {
323:
324: public int getNumber() {
325: return arm.getMeasurements();
326: }
327:
328: public double getMin() {
329: return arm.getMinValue();
330: }
331:
332: public double getMax() {
333: return arm.getMaxValue();
334: }
335:
336: public double getAvg() {
337: return arm.getTotalValue()
338: / arm.getMeasurements();
339: }
340:
341: public double getTotal() {
342: return arm.getTotalValue();
343: }
344:
345: public void add(double measurement, long time) {
346: throw new UnsupportedOperationException(
347: "Read-only");
348: }
349:
350: public void add(Metric metric) {
351: throw new UnsupportedOperationException(
352: "Read-only");
353: }
354:
355: public double getDeviation() {
356: // TODO - Calcualte deviation
357: return 0;
358: }
359:
360: private Collection measurements;
361:
362: public Collection getMeasurements() {
363: if (measurements == null) {
364: // System.out.println("getMeasurements: "+measurementsCounter++);
365: try {
366: //System.out.println("Loading measurements for "+getId()+" "+arm.getName());
367: measurements = factory
368: .getResultsEngine()
369: .getAggregatedResultsMetricMeasurement(
370: id, arm.getName(),
371: new ArrayList(),
372: new Converter() {
373:
374: public Object convert(
375: Object source) {
376: final AggregatedResultsMetricMeasurement armm = (AggregatedResultsMetricMeasurement) source;
377: return new HammurapiMeasurement() {
378: SourceMarker source = new SourceMarker() {
379:
380: public int getLine() {
381: return armm
382: .getLine();
383: }
384:
385: public int getColumn() {
386: return armm
387: .getCol();
388: }
389:
390: public String getSourceURL() {
391: return armm
392: .getSource();
393: }
394:
395: public Integer getSourceId() {
396: return null;
397: }
398:
399: };
400:
401: public SourceMarker getSource() {
402: return source;
403: }
404:
405: public double getValue() {
406: return armm
407: .getMeasurementValue();
408: }
409:
410: public long getTime() {
411: return 0;
412: }
413: };
414: }
415:
416: });
417: } catch (SQLException e) {
418: throw new HammurapiRuntimeException(
419: "Cannot create metric measurement: "
420: + e, e);
421: }
422: }
423: return measurements;
424: }
425:
426: public String getName() {
427: return arm.getName();
428: }
429:
430: });
431: }
432: }
433: return metrics;
434: }
435:
436: public void aggregate(
437: final org.hammurapi.results.AggregatedResults agregee) {
438: final AggregatedResults unWrapped = factory.unWrap(agregee);
439: codeBase += agregee.getCodeBase();
440: reviews += agregee.getReviewsNumber();
441: violationsNumber += agregee.getViolationsNumber();
442: waivedViolationsNumber += agregee.getWaivedViolationsNumber();
443: violationLevel += agregee.getViolationLevel();
444: hasWarnings |= agregee.hasWarnings();
445:
446: try {
447: Number ams = agregee.getMaxSeverity();
448: if (ams != null
449: && (maxSeverity == null || maxSeverity.intValue() > ams
450: .intValue())) {
451: maxSeverity = ams;
452: factory.getResultsEngine()
453: .updateAggregatedResultsMaxSeverity(
454: ams.shortValue(), id);
455: }
456:
457: final Parameterizer parameterizer = new Parameterizer() {
458: public void parameterize(PreparedStatement ps)
459: throws SQLException {
460: idParameterizer.parameterize(ps);
461: ps.setInt(2, unWrapped.getId());
462: }
463: };
464:
465: factory
466: .getSQLProcessor()
467: .processSelect(
468: "SELECT * FROM RESULT_NET WHERE PARENT=? AND CHILD=?",
469: parameterizer, new RowProcessorEx() {
470: public void onEmptyResultSet()
471: throws SQLException {
472: factory
473: .getSQLProcessor()
474: .processUpdate(
475: "INSERT INTO RESULT_NET (PARENT, CHILD) VALUES (?,?)",
476: parameterizer);
477: }
478:
479: public boolean process(ResultSet rs) {
480: // Doing nothing - already set.
481: return false;
482: }
483: });
484:
485: factory
486: .getSQLProcessor()
487: .processUpdate(
488: "INSERT INTO KINDRED (ANCESTOR, DESCENDANT) "
489: + "SELECT A.ANCESTOR, D.DESCENDANT FROM KINDRED A, KINDRED D WHERE A.DESCENDANT=? AND D.ANCESTOR=? ",
490: //"AND NOT EXISTS (SELECT * FROM KINDRED C WHERE C.ANCESTOR=A.ANCESTOR AND C.DESCENDANT=D.DESCENDANT)",
491: new Parameterizer() {
492: public void parameterize(
493: PreparedStatement ps)
494: throws SQLException {
495: ps.setInt(1, getId());
496: ps.setInt(2, unWrapped.getId());
497: }
498: });
499: } catch (SQLException e) {
500: throw new HammurapiRuntimeException(e);
501: }
502: }
503:
504: /**
505: * Sets number of reviews.
506: * @param reviews The reviews to set.
507: */
508: public void setReviewsNumber(final long reviews) {
509: this .reviews = reviews;
510: try {
511: factory.getSQLProcessor().processUpdate(
512: "UPDATE RESULT SET REVIEWS=? WHERE ID=?",
513: new Parameterizer() {
514: public void parameterize(PreparedStatement ps)
515: throws SQLException {
516: ps.setLong(1, reviews);
517: ps.setInt(2, getId());
518: }
519: });
520: } catch (SQLException e) {
521: throw new HammurapiRuntimeException(e);
522: }
523: }
524:
525: public void setCodeBase(final long codeBase) {
526: this .codeBase = codeBase;
527: try {
528: factory.getSQLProcessor().processUpdate(
529: "UPDATE RESULT SET CODEBASE=? WHERE ID=?",
530: new Parameterizer() {
531: public void parameterize(PreparedStatement ps)
532: throws SQLException {
533: ps.setLong(1, codeBase);
534: ps.setInt(2, getId());
535: }
536: });
537: } catch (SQLException e) {
538: throw new HammurapiRuntimeException(e);
539: }
540: }
541:
542: public void addAnnotation(Annotation annotation) {
543: try {
544: final String handle = factory.getStorage().put(annotation);
545: factory
546: .getSQLProcessor()
547: .processUpdate(
548: "INSERT INTO ANNOTATION (RESULT_ID, HANDLE) VALUES (?, ?)",
549: new Parameterizer() {
550: public void parameterize(
551: PreparedStatement ps)
552: throws SQLException {
553: idParameterizer.parameterize(ps);
554: ps.setString(2, handle);
555: }
556: });
557: } catch (SQLException e) {
558: throw new HammurapiRuntimeException(e);
559: } catch (PersistenceException e) {
560: throw new HammurapiRuntimeException(e);
561: }
562: }
563:
564: public Collection getAnnotations() {
565: final Collection ret = new LinkedList();
566: try {
567: factory.getSQLProcessor().processSelect(
568: "SELECT HANDLE FROM ANNOTATION WHERE RESULT_ID=?",
569: idParameterizer, new RowProcessor() {
570: public boolean process(ResultSet rs)
571: throws SQLException {
572: try {
573: ret.add(factory.getStorage().get(
574: rs.getString("HANDLE")));
575: } catch (PersistenceException e) {
576: throw new HammurapiRuntimeException(e);
577: }
578: return true;
579: }
580: });
581: } catch (SQLException e) {
582: throw new HammurapiRuntimeException(e);
583: }
584: return ret;
585: }
586:
587: private WaiverSet waiverSet;
588:
589: /**
590: * @param descriptor
591: * @throws SQLException
592: */
593: protected void maybeInsertInspector(
594: final InspectorDescriptor descriptor) throws SQLException {
595: if (descriptor != null) {
596: factory
597: .getSQLProcessor()
598: .processSelect(
599: "SELECT * FROM INSPECTOR WHERE REPORT_ID=? AND NAME=?",
600: new Parameterizer() {
601: public void parameterize(
602: PreparedStatement preparedStatement)
603: throws SQLException {
604: preparedStatement.setInt(1, factory
605: .getReportId());
606: preparedStatement.setString(2,
607: descriptor.getName());
608: }
609: },
610:
611: new RowProcessorEx() {
612: public boolean process(
613: ResultSet resultSet) {
614: return false;
615: }
616:
617: public void onEmptyResultSet()
618: throws SQLException {
619: factory
620: .getSQLProcessor()
621: .processUpdate(
622: "INSERT INTO INSPECTOR (REPORT_ID, NAME, SEVERITY, DESCRIPTION, CONFIG_INFO) VALUES (?, ?, ?, ?, ?)",
623: new Parameterizer() {
624: public void parameterize(
625: PreparedStatement ps)
626: throws SQLException {
627: ps
628: .setInt(
629: 1,
630: factory
631: .getReportId());
632: ps
633: .setString(
634: 2,
635: descriptor
636: .getName());
637: ps
638: .setShort(
639: 3,
640: descriptor
641: .getSeverity()
642: .shortValue());
643: ps
644: .setString(
645: 4,
646: descriptor
647: .getDescription());
648: try {
649: Inspector inspector = descriptor
650: .getInspector();
651: if (inspector != null) {
652: ps
653: .setString(
654: 5,
655: inspector
656: .getConfigInfo());
657: }
658: } catch (ConfigurationException e) {
659: throw new HammurapiRuntimeException(
660: "Can't obtain inspector configuration info",
661: e);
662: }
663: }
664: });
665: }
666: });
667: }
668: }
669:
670: private Map severitySummary;
671:
672: public Map getSeveritySummary() {
673: if (severitySummary == null) {
674: severitySummary = new TreeMap();
675: Iterator it = factory.getResultsEngine()
676: .getAggregatedResultsSeveritySummary(id).iterator();
677: while (it.hasNext()) {
678: Number severity = (Number) it.next();
679: severitySummary.put(severity,
680: createInspectorSummaryMapProxy(severity));
681: }
682: }
683: return severitySummary;
684: }
685:
686: public Collection getWarnings() {
687: try {
688: return factory.getResultsEngine().getAllWarningsJoined(
689: getId(), new LinkedList(), violationConverter);
690: } catch (SQLException e) {
691: throw new HammurapiRuntimeException(e);
692: }
693: }
694:
695: private Map createInspectorSummaryMapProxy(final Number severity) {
696: return (Map) Proxy.newProxyInstance(
697: getClass().getClassLoader(), new Class[] { Map.class },
698: new InvocationHandler() {
699:
700: private Map target;
701:
702: public Object invoke(Object proxy, Method method,
703: Object[] args) throws Throwable {
704: if (target == null) {
705: target = instantiateInspectorSummaryMap(severity);
706: }
707: return method.invoke(target, args);
708: }
709: });
710: }
711:
712: /**
713: * @param severity
714: * @param map
715: */
716: private Map instantiateInspectorSummaryMap(final Number severity) {
717: class InspectorInfo {
718: String name;
719: String description;
720: String configInfo;
721:
722: InspectorInfo(
723: org.hammurapi.results.persistent.jdbc.sql.Inspector arim) {
724: name = arim.getName();
725: description = arim.getDescription();
726: configInfo = arim.getConfigInfo();
727: }
728:
729: public boolean equals(Object obj) {
730: if (obj == this ) {
731: return true;
732: } else if (obj instanceof InspectorInfo) {
733: InspectorInfo otherInfo = (InspectorInfo) obj;
734: return equalStrings(name, otherInfo.name)
735: && equalStrings(description,
736: otherInfo.description)
737: && equalStrings(configInfo,
738: otherInfo.configInfo);
739: } else {
740: return super .equals(obj);
741: }
742: }
743:
744: boolean equalStrings(String a, String b) {
745: if (a == null) {
746: return b == null;
747: }
748:
749: return a.equals(b);
750: }
751:
752: public int hashCode() {
753: return (name == null ? 0 : name.hashCode())
754: ^ (description == null ? 0 : description
755: .hashCode())
756: ^ (configInfo == null ? 0 : configInfo
757: .hashCode());
758: }
759: }
760:
761: final Map infoMap = new HashMap();
762:
763: Iterator it = factory.getResultsEngine()
764: .getAggregatedResultsInspectorSummary(id,
765: severity.shortValue()).iterator();
766: while (it.hasNext()) {
767: org.hammurapi.results.persistent.jdbc.sql.Inspector arim = (org.hammurapi.results.persistent.jdbc.sql.Inspector) it
768: .next();
769: InspectorInfo inspectorInfo = new InspectorInfo(arim);
770: Set ids = (Set) infoMap.get(inspectorInfo);
771: if (ids == null) {
772: ids = new HashSet();
773: infoMap.put(inspectorInfo, ids);
774: }
775:
776: ids.add(new Integer(arim.getReportId()));
777: }
778:
779: final Map map = new TreeMap();
780: it = infoMap.entrySet().iterator();
781: while (it.hasNext()) {
782: Map.Entry entry = (Map.Entry) it.next();
783: InspectorInfo info = (InspectorInfo) entry.getKey();
784: Set ids = (Set) entry.getValue();
785: StringBuffer sb = new StringBuffer();
786: Iterator iit = ids.iterator();
787: while (iit.hasNext()) {
788: sb.append(iit.next());
789: if (iit.hasNext()) {
790: sb.append(",");
791: }
792: }
793:
794: map.put(info.name + " [" + sb.toString() + "]",
795: createInspectorSummary(severity, info.name,
796: info.description, info.configInfo, sb
797: .toString()));
798: }
799:
800: return map;
801: }
802:
803: /**
804: * @param severity
805: * @param inspectorName
806: * @param description
807: * @param configInfo
808: * @return inspector summary
809: */
810: private InspectorSummary createInspectorSummary(
811: final Number severity, final String inspectorName,
812: final String description, final String configInfo,
813: final String inspectorReportIds) {
814: return new InspectorSummary() {
815:
816: public String getDescription() {
817: return description;
818: }
819:
820: private List locations;
821:
822: public List getLocations() {
823: if (locations == null) {
824: locations = new ArrayList();
825: Iterator it = factory.getResultsEngine()
826: .getAggregatedResultsInspectorViolations(
827: id, inspectorName).iterator();
828: while (it.hasNext()) {
829: final AggregatedResultsInspectorViolations ariv = (AggregatedResultsInspectorViolations) it
830: .next();
831: locations.add(new SourceMarker() {
832:
833: public int getLine() {
834: return ariv.getLine();
835: }
836:
837: public int getColumn() {
838: return ariv.getCol();
839: }
840:
841: public String getSourceURL() {
842: if (ariv.getCompilationUnitPackage() == null
843: || ariv
844: .getCompilationUnitPackage()
845: .length() == 0) {
846: return ariv
847: .getCompilationUnitName();
848: }
849:
850: return ariv.getCompilationUnitPackage()
851: .replace('.', '/')
852: + '/'
853: + ariv.getCompilationUnitName();
854: }
855:
856: public Integer getSourceId() {
857: return ariv.getSourceId();
858: }
859:
860: });
861: }
862: }
863:
864: return locations;
865: }
866:
867: public int getLocationsCount() {
868: return getLocations().size();
869: }
870:
871: public String getName() {
872: return inspectorName;
873: }
874:
875: public Number getSeverity() {
876: return severity;
877: }
878:
879: public String getConfigInfo() {
880: return configInfo;
881: }
882:
883: public int compareTo(Object o) {
884: if (o instanceof InspectorSummary) {
885: return inspectorName
886: .compareTo(((InspectorSummary) o).getName());
887: } else if (o instanceof Comparable) {
888: return -((Comparable) o).compareTo(this );
889: } else {
890: return this .hashCode() - o.hashCode();
891: }
892: }
893:
894: public String getVersion() {
895: return inspectorReportIds;
896: }
897:
898: private int baseLineLocationsCount = -1;
899:
900: public int getBaseLineLocationsCount() {
901: if (baseLineLocationsCount == -1 && baseLineId != null) {
902: try {
903: baseLineLocationsCount = factory
904: .getResultsEngine()
905: .getAggregatedResultsInspectorViolationsCount(
906: baseLineId.intValue(),
907: inspectorName);
908: } catch (SQLException e) {
909: throw new HammurapiRuntimeException(e);
910: }
911: }
912: return baseLineLocationsCount;
913: }
914: };
915: }
916:
917: protected Converter violationConverter = new Converter() {
918: public Object convert(Object o) {
919: final ViolationJoined vj = (ViolationJoined) o;
920: String path;
921: if (vj.getCompilationUnitPackage() == null
922: || vj.getCompilationUnitPackage().length() == 0) {
923: path = vj.getCompilationUnitName();
924: } else {
925: path = vj.getCompilationUnitPackage().replace('.', '/')
926: + '/' + vj.getCompilationUnitName();
927: }
928: return new SimpleViolation(new SimpleSourceMarker(vj
929: .getCol(), vj.getLine(), path, vj.getSourceId()),
930: vj.getMessage(), factory.getInspectorDescriptor(vj
931: .getInspector()));
932: }
933: };
934:
935: private Integer baseLineId;
936:
937: public WaiverSet getWaiverSet() {
938: return waiverSet;
939: }
940:
941: public void commit() throws HammurapiException {
942: try {
943: factory.getResultsEngine().commit(getId());
944: } catch (SQLException e) {
945: throw new HammurapiException(e);
946: }
947: }
948:
949: public boolean isNew() {
950: try {
951: return factory.getResultsEngine().getAggregateResultsIsNew(
952: id) > 0;
953: } catch (SQLException e) {
954: throw new HammurapiRuntimeException(e);
955: }
956: }
957:
958: private BasicResults baseLine;
959:
960: public org.hammurapi.results.BasicResults getBaseLine() {
961: if (baseLineId != null && baseLine == null) {
962: try {
963: baseLine = new BasicResults(baseLineId.intValue(),
964: factory);
965: } catch (SQLException e) {
966: throw new HammurapiRuntimeException(e);
967: }
968: }
969:
970: return baseLine;
971: }
972:
973: /**
974: * @param baseLineId
975: */
976: void setBaseLineId(Integer baseLineId) {
977: this.baseLineId = baseLineId;
978: }
979: }
|