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;
024:
025: import java.util.ArrayList;
026: import java.util.Collection;
027: import java.util.Collections;
028: import java.util.HashMap;
029: import java.util.HashSet;
030: import java.util.Iterator;
031: import java.util.LinkedList;
032: import java.util.List;
033: import java.util.Map;
034: import java.util.Set;
035:
036: import com.pavelvlasov.config.ConfigurationException;
037: import com.pavelvlasov.logging.Logger;
038:
039: /**
040: * @author Pavel Vlasov
041: * @version $Revision: 1.8 $
042: */
043: public class InspectorSet {
044: private Map descriptors = new HashMap();
045: private Collection inspectors;
046: private Logger logger;
047: private InspectorContextFactory contextFactory;
048: private Collection inspectorSourceInfos = new ArrayList();
049:
050: public InspectorSet(InspectorContextFactory contextFactory,
051: Logger logger) {
052: this .contextFactory = contextFactory;
053: this .logger = logger;
054: }
055:
056: public void addDescriptors(Collection descriptors)
057: throws ConfigurationException {
058: Iterator it = descriptors.iterator();
059: while (it.hasNext()) {
060: addDescriptor((InspectorDescriptor) it.next());
061: }
062: }
063:
064: public void addInspectorSourceInfo(InspectorSourceInfo info) {
065: inspectorSourceInfos.add(info);
066: }
067:
068: public Collection getInspectorSourceInfos() {
069: return inspectorSourceInfos;
070: }
071:
072: public InspectorDescriptor getDescriptor(String name) {
073: return (InspectorDescriptor) descriptors.get(name);
074: }
075:
076: public Collection getDescriptors() {
077: return descriptors.values();
078: }
079:
080: public void addDescriptor(InspectorDescriptor descriptor)
081: throws ConfigurationException {
082: SelfDescribingInspectorProxy sdrp = new SelfDescribingInspectorProxy(
083: descriptor);
084: String inspectorName = descriptor.getName();
085: if (inspectorName == null) {
086: inspectorName = sdrp.getName();
087: }
088:
089: if (inspectorName == null) {
090: throw new ConfigurationException("Unnamed inspector");
091: }
092:
093: InspectorDescriptorStack rds = (InspectorDescriptorStack) descriptors
094: .get(inspectorName);
095: if (rds == null) {
096: rds = new InspectorDescriptorStack();
097: descriptors.put(inspectorName, rds);
098: }
099:
100: rds.addFirst(sdrp);
101: rds.addFirst(descriptor);
102: }
103:
104: public Collection getInspectors() throws ConfigurationException,
105: HammurapiException {
106: if (inspectors == null) {
107: assignOrders();
108: inspectors = new LinkedList();
109: Iterator it = descriptors.values().iterator();
110: while (it.hasNext()) {
111: InspectorDescriptor inspectorDescriptor = (InspectorDescriptor) it
112: .next();
113: InspectorContext ic = contextFactory.newContext(
114: inspectorDescriptor, logger);
115: if (Boolean.TRUE
116: .equals(inspectorDescriptor.isEnabled())) {
117: Inspector inspector = inspectorDescriptor
118: .getInspector();
119: if (inspector != null) {
120: inspector.setContext(ic);
121: inspectors.add(inspector);
122:
123: if (inspector instanceof FilteringInspector) {
124: Collection fid = inspectorDescriptor
125: .getFilteredInspectorDesriptors(
126: this , null);
127: if (fid != null) {
128: Iterator dit = fid.iterator();
129: while (dit.hasNext()) {
130: ((FilteringInspector) inspector)
131: .addTarget(((InspectorDescriptor) dit
132: .next())
133: .getInspector());
134: }
135: }
136: }
137: }
138: }
139: }
140: }
141: return inspectors;
142: }
143:
144: /**
145: * Invokes init() for all inspectors in the set
146: * @throws HammurapiException
147: * @throws ConfigurationException
148: */
149: public void initInspectors() throws ConfigurationException,
150: HammurapiException {
151: Iterator it = getInspectors().iterator();
152: while (it.hasNext()) {
153: ((Inspector) it.next()).init();
154: }
155: }
156:
157: private void assignOrders() throws HammurapiException {
158: final Map dependencyMap = new HashMap();
159: Iterator it = descriptors.values().iterator();
160: while (it.hasNext()) {
161: InspectorDescriptor inspectorDescriptor = (InspectorDescriptor) it
162: .next();
163: if (Boolean.TRUE.equals(inspectorDescriptor.isEnabled())) {
164: Collection inspectorsToOrder = new ArrayList();
165: Collection waivedInspectorNames = inspectorDescriptor
166: .getWaivedInspectorNames();
167: if (waivedInspectorNames != null) {
168: inspectorsToOrder.addAll(waivedInspectorNames);
169: }
170:
171: Collection filteredInspectors = inspectorDescriptor
172: .getFilteredInspectorDesriptors(this , null);
173: if (filteredInspectors != null
174: && !filteredInspectors.isEmpty()) {
175: Iterator fit = filteredInspectors.iterator();
176: while (fit.hasNext()) {
177: inspectorsToOrder
178: .add(((InspectorDescriptor) fit.next())
179: .getName());
180: }
181: }
182:
183: Collection afterInspectors = inspectorDescriptor
184: .getAfterInspectorNames();
185: if (afterInspectors != null) {
186: inspectorsToOrder.addAll(afterInspectors);
187: }
188:
189: dependencyMap.put(inspectorDescriptor.getName(),
190: inspectorsToOrder);
191: }
192: }
193:
194: class GraphEntry implements Comparable {
195: private static final String CICRULAR_REFERENCE_MSG = "Circular <waives> or <filter> reference in inspector '";
196: String name;
197: private Set dependents = new HashSet();
198: private boolean ready = false;
199: private int level;
200:
201: public String toString() {
202: StringBuffer ret = new StringBuffer(getClass()
203: .getName());
204: ret.append("[").append(name);
205: if (!dependents.isEmpty()) {
206: ret.append(" <- ");
207: Iterator it = dependents.iterator();
208: while (it.hasNext()) {
209: ret.append(it.next());
210: if (it.hasNext()) {
211: ret.append(", ");
212: }
213: }
214: }
215: ret.append("]");
216: return ret.toString();
217: }
218:
219: GraphEntry(String name) throws HammurapiException {
220: this .name = name;
221: Iterator it = ((Collection) dependencyMap.get(name))
222: .iterator();
223: while (it.hasNext()) {
224: String dependent = (String) it.next();
225: if (name.equals(dependent)) {
226: throw new HammurapiException(
227: CICRULAR_REFERENCE_MSG + name + "'");
228: }
229: dependents.add(dependent);
230:
231: Object o = dependencyMap.get(dependent);
232: if (o instanceof Collection) {
233: o = new GraphEntry(dependent);
234: level = Math.max(level,
235: ((GraphEntry) o).level + 1);
236: }
237:
238: if (o != null) {
239: Iterator dit = ((GraphEntry) o).getDependents()
240: .iterator();
241: while (dit.hasNext()) {
242: String ddependent = (String) it.next();
243: if (name.equals(ddependent)) {
244: throw new HammurapiException(
245: CICRULAR_REFERENCE_MSG + name
246: + "'");
247: }
248:
249: dependents.add(ddependent);
250: }
251: }
252: }
253: ready = true;
254: dependencyMap.put(name, this );
255: }
256:
257: Set getDependents() throws HammurapiException {
258: if (ready) {
259: return dependents;
260: }
261:
262: throw new HammurapiException(CICRULAR_REFERENCE_MSG
263: + name + "'");
264: }
265:
266: public int compareTo(Object o) {
267: if (o == this ) {
268: return 0;
269: } else if (o instanceof GraphEntry) {
270: GraphEntry ge = (GraphEntry) o;
271:
272: try {
273: if (getDependents().contains(ge.name)) {
274: return -1;
275: } else if (ge.getDependents().contains(name)) {
276: return 1;
277: } else if (level < ge.level) {
278: return 1;
279: } else if (level > ge.level) {
280: return -1;
281: } else {
282: return name.compareTo(ge.name);
283: }
284: } catch (HammurapiException e) {
285: throw new HammurapiRuntimeException(e);
286: }
287: } else {
288: return -1;
289: }
290: }
291:
292: public int hashCode() {
293: return name.hashCode();
294: }
295: }
296:
297: Iterator kit = dependencyMap.keySet().iterator();
298: while (kit.hasNext()) {
299: String key = (String) kit.next();
300: if (dependencyMap.get(key) instanceof Collection) {
301: new GraphEntry(key);
302: }
303: }
304:
305: List inspectors = new ArrayList(dependencyMap.values());
306: Collections.sort(inspectors);
307:
308: int counter = 0;
309: Integer start = null;
310: Iterator wit = inspectors.iterator();
311: while (wit.hasNext()) {
312: String iName = ((GraphEntry) wit.next()).name;
313: InspectorDescriptor id = (InspectorDescriptor) descriptors
314: .get(iName);
315: Integer order = id.getOrder();
316: if (order != null) {
317: start = new Integer(order.intValue() - counter);
318: break;
319: }
320: counter++;
321: }
322:
323: counter = start == null ? 0 : start.intValue();
324: wit = inspectors.iterator();
325: while (wit.hasNext()) {
326: String iName = ((GraphEntry) wit.next()).name;
327: InspectorDescriptor id = (InspectorDescriptor) descriptors
328: .get(iName);
329: Integer order = id.getOrder();
330: if (order != null) {
331: if (order.intValue() < counter) {
332: throw new HammurapiException(
333: "Order "
334: + order.intValue()
335: + " conflicts with automatically assigned order "
336: + counter + " for inspector "
337: + iName);
338: }
339:
340: counter = order.intValue();
341: } else {
342: final Integer iOrder = new Integer(counter);
343: descriptors.put(id.getName(),
344: new InspectorDescriptorFilter(id) {
345: public Integer getOrder() {
346: return iOrder;
347: }
348: });
349: }
350: counter++;
351: }
352: }
353:
354: int size() {
355: return descriptors.size();
356: }
357:
358: /**
359: * Calls destroy() for all inspectors
360: */
361: public void destroy() {
362: if (inspectors != null) {
363: Iterator it = inspectors.iterator();
364: while (it.hasNext()) {
365: ((Inspector) it.next()).destroy();
366: }
367: }
368: }
369: }
|