KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hammurapi > results > persistent > jdbc > ResultsFactory


1 /*
2  * Hammurapi
3  * Automated Java code review system.
4  * Copyright (C) 2004 Hammurapi Group
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  * URL: http://www.hammurapi.org
21  * e-Mail: support@hammurapi.biz
22  */

23 package org.hammurapi.results.persistent.jdbc;
24
25 import java.lang.reflect.Constructor JavaDoc;
26 import java.lang.reflect.InvocationHandler JavaDoc;
27 import java.lang.reflect.InvocationTargetException JavaDoc;
28 import java.lang.reflect.Method JavaDoc;
29 import java.lang.reflect.Proxy JavaDoc;
30 import java.sql.Connection JavaDoc;
31 import java.sql.PreparedStatement JavaDoc;
32 import java.sql.ResultSet JavaDoc;
33 import java.sql.SQLException JavaDoc;
34 import java.sql.Timestamp JavaDoc;
35 import java.util.LinkedList JavaDoc;
36 import java.util.Set JavaDoc;
37
38 import org.hammurapi.HammurapiException;
39 import org.hammurapi.HammurapiRuntimeException;
40 import org.hammurapi.InspectorDescriptor;
41 import org.hammurapi.InspectorSet;
42 import org.hammurapi.WaiverSet;
43 import org.hammurapi.results.persistent.jdbc.sql.Report;
44 import org.hammurapi.results.persistent.jdbc.sql.ReportImpl;
45 import org.hammurapi.results.persistent.jdbc.sql.ResultsEngine;
46
47 import com.pavelvlasov.cache.AbstractProducer;
48 import com.pavelvlasov.cache.Entry;
49 import com.pavelvlasov.cache.MemoryCache;
50 import com.pavelvlasov.convert.CompositeConverter;
51 import com.pavelvlasov.jsel.CompilationUnit;
52 import com.pavelvlasov.jsel.JselException;
53 import com.pavelvlasov.jsel.Repository;
54 import com.pavelvlasov.jsel.impl.DbRepositoryImpl;
55 import com.pavelvlasov.metrics.MeasurementCategoryFactory;
56 import com.pavelvlasov.persistence.Storage;
57 import com.pavelvlasov.sql.Parameterizer;
58 import com.pavelvlasov.sql.RowProcessor;
59 import com.pavelvlasov.sql.RowProcessorEx;
60 import com.pavelvlasov.sql.SQLProcessor;
61 import com.pavelvlasov.wrap.WrapperHandler;
62
63 /**
64  * @author Pavel Vlasov
65  * @version $Revision: 1.16 $
66  */

67 public class ResultsFactory extends org.hammurapi.results.ResultsFactory {
68     private final class Deferrer implements InvocationHandler JavaDoc {
69         private final AggregatedResults results;
70
71         private Deferrer(AggregatedResults results) {
72             super();
73             this.results = results;
74         }
75
76         public Object JavaDoc invoke(Object JavaDoc proxy, final Method JavaDoc method, final Object JavaDoc[] args) throws Throwable JavaDoc {
77             if (joined || Thread.currentThread()==taskThread) {
78                 return method.invoke(results, args);
79             }
80             
81             if (method.getDeclaringClass().getName().equals("java.lang.Object")) {
82                 return method.invoke(results, args);
83             } else if (method.getReturnType().equals(void.class)) {
84                 execute(
85                         new Task() {
86
87                             public void execute() throws HammurapiException {
88                                 try {
89                                     method.invoke(results, args);
90                                 } catch (IllegalArgumentException JavaDoc e) {
91                                     throw new HammurapiException(e);
92                                 } catch (IllegalAccessException JavaDoc e) {
93                                     throw new HammurapiException(e);
94                                 } catch (InvocationTargetException JavaDoc e) {
95                                     throw new HammurapiException(e);
96                                 }
97                             }
98                             
99                         });
100                 return null;
101             } else {
102                 throw new HammurapiException("Non-void method "+method+" can't be executed in a separate thread");
103             }
104         }
105     }
106
107     private WaiverSet waiverSet;
108     private SQLProcessor sqlProcessor;
109     
110     private MemoryCache resultsCache=new MemoryCache(new AbstractProducer() {
111
112         public Entry get(Object JavaDoc key) {
113             try {
114                 int resultId=((Number JavaDoc) key).intValue();
115 // System.out.println("Key: "+key.getClass()+" - "+key);
116
Class JavaDoc resultClass=getClass().getClassLoader().loadClass(getResultsEngine().getResultType(resultId));
117 // System.out.println("Result class: "+resultClass);
118
Constructor JavaDoc resultConstructor=resultClass.getConstructor(new Class JavaDoc[]{int.class,ResultsFactory.class});
119                 final Object JavaDoc result = resultConstructor.newInstance(new Object JavaDoc[]{CompositeConverter.getDefaultConverter().convert(key, Integer JavaDoc.class, false),ResultsFactory.this});
120                 return new Entry() {
121
122                     public long getExpirationTime() {
123                         return 0;
124                     }
125
126                     public long getTime() {
127                         return 0;
128                     }
129
130                     public Object JavaDoc get() {
131                         return result;
132                     }
133                     
134                 };
135                 
136             } catch (IllegalArgumentException JavaDoc e) {
137                 throw new HammurapiRuntimeException(e);
138             } catch (SecurityException JavaDoc e) {
139                 throw new HammurapiRuntimeException(e);
140             } catch (InstantiationException JavaDoc e) {
141                 throw new HammurapiRuntimeException(e);
142             } catch (IllegalAccessException JavaDoc e) {
143                 throw new HammurapiRuntimeException(e);
144             } catch (InvocationTargetException JavaDoc e) {
145                 throw new HammurapiRuntimeException(e);
146             } catch (NoSuchMethodException JavaDoc e) {
147                 throw new HammurapiRuntimeException(e);
148             } catch (ClassNotFoundException JavaDoc e) {
149                 throw new HammurapiRuntimeException(e);
150             } catch (SQLException JavaDoc e) {
151                 throw new HammurapiRuntimeException(e);
152             }
153         }
154
155         public Set JavaDoc keySet() {
156             return null;
157         }
158         
159     },
160     null,
161     MeasurementCategoryFactory.getCategory(getClass().getName()+".resultsCache"));
162     
163     SQLProcessor getSQLProcessor() {
164         return sqlProcessor;
165     }
166     
167     private ResultsEngine resultsEngine;
168     private Number JavaDoc baseLineId;
169     private String JavaDoc name;
170     
171     ResultsEngine getResultsEngine() {
172         if (resultsEngine==null) {
173             resultsEngine=new ResultsEngine(getSQLProcessor());
174         }
175         return resultsEngine;
176     }
177     
178     int nextPK(final String JavaDoc keyName) throws SQLException JavaDoc {
179         Connection JavaDoc con=sqlProcessor.getConnection();
180         try {
181             boolean ac=con.getAutoCommit();
182             try {
183                 con.setAutoCommit(false);
184                 final Parameterizer parameterizer=new Parameterizer() {
185                     public void parameterize(PreparedStatement JavaDoc preparedStatement) throws SQLException JavaDoc {
186                         preparedStatement.setString(1, keyName);
187                     }
188                 };
189                 
190                 final int[] value={0};
191                 
192                 sqlProcessor.processSelect(
193                         "SELECT KEY_VALUE FROM PRIMARY_KEY WHERE KEY_NAME=?",
194                         parameterizer,
195                         new RowProcessorEx() {
196                             public boolean process(ResultSet JavaDoc resultSet) throws SQLException JavaDoc {
197                                 value[0]=resultSet.getInt("KEY_VALUE")+1;
198                                 sqlProcessor.processUpdate("UPDATE PRIMARY_KEY SET KEY_VALUE=KEY_VALUE+1 WHERE KEY_NAME=?", parameterizer);
199                                 return false;
200                             }
201
202                             public void onEmptyResultSet() throws SQLException JavaDoc {
203                                 sqlProcessor.processUpdate("INSERT INTO PRIMARY_KEY (KEY_NAME, KEY_VALUE) VALUES (?, 0)", parameterizer);
204                             }
205                         });
206                 
207                 return value[0];
208             } finally {
209                 con.setAutoCommit(ac);
210             }
211         } finally {
212             sqlProcessor.releaseConnection(con);
213         }
214     }
215
216     public ResultsFactory(final ResultsFactoryConfig config) throws SQLException JavaDoc, HammurapiException {
217         this.sqlProcessor=config.getSqlProcessor();
218         //sqlProcessor.setMetricConsumer(new StackCountingMetricConsumer(1));
219
this.waiverSet=config.getWaiverSet();
220         this.inspectorSet=config.getInspectorSet();
221         this.repository=config.getRepository();
222         this.storage=config.getStorage();
223         this.name=config.getName();
224         
225         reportId=nextPK("REPORT");
226         Report report=new ReportImpl(true);
227         report.setId(reportId);
228         report.setName(config.getName());
229         report.setDescription(config.getDescription());
230         report.setReportNumber(new Integer JavaDoc(config.getReportNumber()));
231         report.setHostId(config.getHostId());
232         report.setHostName(config.getHostName());
233         getResultsEngine().insertReport(report);
234         
235         if (config.getBaseLine()!=null) {
236             baseLineId=getResultsEngine().getBaseLineIdByDate(config.getName(), new Timestamp JavaDoc(config.getBaseLine().getTime()));
237             if (baseLineId==null) {
238                 throw new HammurapiException("Baseline report not found for "+config.getBaseLine());
239             }
240         }
241     }
242     
243     public void setSummary(final org.hammurapi.results.AggregatedResults results) {
244         try {
245             AggregatedResults aggregatedResults = unWrap(results);
246             getResultsEngine().setReportResult(aggregatedResults.getId(), reportId);
247             aggregatedResults.setBaseLineId((Integer JavaDoc) CompositeConverter.getDefaultConverter().convert(baseLineId, Integer JavaDoc.class, false));
248         } catch (SQLException JavaDoc e) {
249             throw new HammurapiRuntimeException(e);
250         }
251     }
252
253     /**
254      * @param results
255      * @return Unwrapped result.
256      */

257     AggregatedResults unWrap(final org.hammurapi.results.AggregatedResults results) {
258         return Proxy.isProxyClass(results.getClass()) ? ((Deferrer) Proxy.getInvocationHandler(results)).results : (AggregatedResults) results;
259     }
260
261     public org.hammurapi.results.AggregatedResults newAggregatedResults() {
262         try {
263             return (org.hammurapi.results.AggregatedResults) proxy(new AggregatedResults(waiverSet, this));
264         } catch (SQLException JavaDoc e) {
265             throw new HammurapiRuntimeException(e);
266         }
267     }
268
269     public org.hammurapi.results.NamedResults newNamedResults(String JavaDoc name) {
270         try {
271             return (org.hammurapi.results.NamedResults) proxy(new NamedResults(name, waiverSet, this));
272         } catch (SQLException JavaDoc e) {
273             throw new HammurapiRuntimeException(e);
274         }
275     }
276
277     public org.hammurapi.results.DetailedResults newDetailedResults(String JavaDoc name) {
278         try {
279             return (org.hammurapi.results.DetailedResults) proxy(new DetailedResults(name, waiverSet, this));
280         } catch (SQLException JavaDoc e) {
281             throw new HammurapiRuntimeException(e);
282         }
283     }
284
285     public org.hammurapi.results.CompositeResults newCompositeResults(String JavaDoc name) {
286         try {
287             return (org.hammurapi.results.CompositeResults) proxy(new CompositeResults(name, waiverSet, this));
288         } catch (SQLException JavaDoc e) {
289             throw new HammurapiRuntimeException(e);
290         }
291     }
292
293     public org.hammurapi.results.ReviewResults newReviewResults(CompilationUnit compilationUnit) {
294         try {
295             return (org.hammurapi.results.ReviewResults) proxy(new ReviewResults(compilationUnit, waiverSet, this));
296         } catch (SQLException JavaDoc e) {
297             throw new HammurapiRuntimeException(e);
298         }
299     }
300     
301     private InspectorSet inspectorSet;
302     private int reportId;
303     
304     /**
305      * @return report Id
306      */

307     public int getReportId() {
308         return reportId;
309     }
310     
311     private Storage storage;
312     
313     public Storage getStorage() {
314         return storage;
315     }
316
317     public InspectorDescriptor getInspectorDescriptor(String JavaDoc string) {
318         return inspectorSet.getDescriptor(string);
319     }
320
321     private Repository repository;
322     
323     public static final String JavaDoc HYPERSONIC_INIT_SCRIPT = "org/hammurapi/results/persistent/jdbc/Hammurapi.Hypersonic.sql";
324     public static final String JavaDoc CLOUDSCAPE_INIT_SCRIPT = "org/hammurapi/results/persistent/jdbc/Hammurapi.Cloudscape.sql";
325     
326     public CompilationUnit getCompilationUnit(int id) throws JselException {
327         return repository.getCompilationUnit(id);
328     }
329
330     public org.hammurapi.results.ReviewResults findReviewResults(final CompilationUnit cu) {
331         try {
332             final ReviewResults[] ret={null};
333             getSQLProcessor().processSelect(
334                     "SELECT ID, TYPE FROM RESULT WHERE COMPILATION_UNIT=? AND COMMITED=1",
335                     new Parameterizer() {
336                         public void parameterize(PreparedStatement JavaDoc ps) throws SQLException JavaDoc {
337                             ps.setInt(1, cu.getSourceId().intValue());
338                         }
339                     },
340                     new RowProcessor() {
341                         public boolean process(final ResultSet JavaDoc rs) {
342                             try {
343                                 Constructor JavaDoc constructor = getClass().getClassLoader().loadClass(
344                                         rs.getString("TYPE")).getConstructor(new Class JavaDoc[]{int.class,ResultsFactory.class});
345                                 ret[0]=(ReviewResults) constructor.newInstance(new Object JavaDoc[]{
346                                         new Integer JavaDoc(rs.getInt("ID")),
347                                         ResultsFactory.this});
348                                 
349                                 sqlProcessor.processUpdate(
350                                         "UPDATE RESULT SET IS_NEW=0 WHERE ID=?",
351                                         new Parameterizer() {
352                                             public void parameterize(PreparedStatement JavaDoc ps) throws SQLException JavaDoc {
353                                                 ps.setInt(1, rs.getInt("ID"));
354                                             }
355                                         });
356                             } catch (IllegalArgumentException JavaDoc e) {
357                                 throw new HammurapiRuntimeException(e);
358                             } catch (SecurityException JavaDoc e) {
359                                 throw new HammurapiRuntimeException(e);
360                             } catch (InstantiationException JavaDoc e) {
361                                 throw new HammurapiRuntimeException(e);
362                             } catch (IllegalAccessException JavaDoc e) {
363                                 throw new HammurapiRuntimeException(e);
364                             } catch (InvocationTargetException JavaDoc e) {
365                                 throw new HammurapiRuntimeException(e);
366                             } catch (NoSuchMethodException JavaDoc e) {
367                                 throw new HammurapiRuntimeException(e);
368                             } catch (ClassNotFoundException JavaDoc e) {
369                                 throw new HammurapiRuntimeException(e);
370                             } catch (SQLException JavaDoc e) {
371                                 throw new HammurapiRuntimeException(e);
372                             }
373                             return false;
374                         }
375                     });
376             return ret[0];
377         } catch (SQLException JavaDoc e) {
378             throw new HammurapiRuntimeException(e);
379         }
380     }
381     
382     public void commit(long executionTime) {
383         try {
384             getResultsEngine().setReportExecutionTime(executionTime, reportId);
385         } catch (SQLException JavaDoc e) {
386             throw new HammurapiRuntimeException(e);
387         }
388     }
389
390     /**
391      * Adds a message to message table if it is not exists.
392      * Returns message id.
393      */

394     int addMessage(String JavaDoc message) {
395         return ((DbRepositoryImpl) repository).addMessage(message);
396     }
397     
398     public void shutdown() {
399         resultsCache.stop();
400     }
401
402     /**
403      * @param results
404      */

405     void addToCache(BasicResults results) {
406         resultsCache.put(new Integer JavaDoc(results.getId()), results, 0, 0);
407     }
408     
409     BasicResults getResult(Object JavaDoc id) {
410         Entry entry = resultsCache.get(id);
411         return (BasicResults) (entry==null ? null : entry.get());
412     }
413
414     /**
415      * @throws HammurapiException
416      *
417      */

418     public void cleanupOldReports() throws HammurapiException {
419         try {
420             getResultsEngine().setOldReports(getReportId(), name);
421             getResultsEngine().deleteOldResults();
422         } catch (SQLException JavaDoc e) {
423             throw new HammurapiException("Could not delete old results: "+e, e);
424         }
425         
426     }
427     
428     private LinkedList JavaDoc tasks=new LinkedList JavaDoc();
429     private static final int MAX_QUEUE=1000;
430     
431     private boolean terminated;
432     
433     private void checkTerminated() throws HammurapiException {
434         synchronized (tasks) {
435             if (terminated) {
436                 throw new HammurapiException("Results processing thread was terminated prematurely");
437             }
438         }
439     }
440     
441     private Thread JavaDoc taskThread=new Thread JavaDoc() {
442         {
443             setName("Results processing thread");
444             start();
445         }
446
447         public void run() {
448             try {
449                 while (true) {
450                     Task task;
451                     synchronized (tasks) {
452                         while (tasks.isEmpty()) {
453                             try {
454                                 tasks.wait();
455                             } catch (InterruptedException JavaDoc e) {
456                                 return;
457                             }
458                         }
459                         
460                         task=(Task) tasks.removeFirst();
461                         if (tasks.size()<MAX_QUEUE) {
462                             tasks.notifyAll();
463                         }
464                     }
465                     
466                     if (task==null) {
467                         return;
468                     }
469                     
470                     task.execute();
471                 }
472             } catch (Exception JavaDoc e) {
473                 e.printStackTrace();
474             } finally {
475                 synchronized (tasks) {
476                     terminated=true;
477                     tasks.notifyAll();
478                 }
479             }
480         }
481     };
482
483     /**
484      * Executes task in a separate thread
485      */

486     public void execute(Task task) throws HammurapiException {
487         if (task!=null) {
488             synchronized (tasks) {
489                 checkTerminated();
490                 
491                 if (tasks.size()>=MAX_QUEUE) {
492                     try {
493                         tasks.wait();
494                         checkTerminated();
495                     } catch (InterruptedException JavaDoc e) {
496                         throw new HammurapiException(e);
497                     }
498                 }
499
500                 tasks.add(task);
501                 tasks.notifyAll();
502             }
503         }
504     }
505         
506     private Object JavaDoc proxy(final AggregatedResults results) {
507         return Proxy.newProxyInstance(
508                 results.getClass().getClassLoader(),
509                 WrapperHandler.getClassInterfaces(results.getClass()),
510                 new Deferrer(results));
511     }
512     
513     private boolean joined;
514
515     public void join() throws HammurapiException {
516         checkTerminated();
517         
518         synchronized (tasks) {
519             tasks.add(null);
520             tasks.notifyAll();
521         }
522         
523         try {
524             taskThread.join();
525         } catch (InterruptedException JavaDoc e) {
526             throw new HammurapiException(e);
527         }
528         
529         joined=true;
530     }
531     
532     String JavaDoc getName() {
533         return name;
534     }
535 }
536
Popular Tags