KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > vladium > emma > report > ReportProperties


1 /* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved.
2  *
3  * This program and the accompanying materials are made available under
4  * the terms of the Common Public License v1.0 which accompanies this distribution,
5  * and is available at http://www.eclipse.org/legal/cpl-v10.html
6  *
7  * $Id: ReportProperties.java,v 1.1.1.1 2004/05/09 16:57:38 vlad_r Exp $
8  */

9 package com.vladium.emma.report;
10
11 import java.io.File JavaDoc;
12 import java.util.HashSet JavaDoc;
13 import java.util.Set JavaDoc;
14 import java.util.StringTokenizer JavaDoc;
15
16 import com.vladium.util.Files;
17 import com.vladium.util.IProperties;
18 import com.vladium.util.IntIntMap;
19 import com.vladium.util.IntVector;
20 import com.vladium.util.ObjectIntMap;
21 import com.vladium.util.Property;
22 import com.vladium.util.asserts.$assert;
23 import com.vladium.emma.IAppErrorCodes;
24 import com.vladium.emma.EMMARuntimeException;
25
26 // ----------------------------------------------------------------------------
27
/**
28  * @author Vlad Roubtsov, (C) 2003
29  */

30 public
31 abstract class ReportProperties implements IAppErrorCodes
32 {
33     // public: ................................................................
34

35     
36     public static final IProperties.IMapper REPORT_PROPERTY_MAPPER; // set in <clinit>
37

38        
39     public static final class ParsedProperties
40     {
41         public void setOutEncoding (final String JavaDoc outEncoding)
42         {
43             if ($assert.ENABLED) $assert.ASSERT (outEncoding != null, "null input: outEncoding");
44             
45             m_outEncoding = outEncoding;
46         }
47
48         public String JavaDoc getOutEncoding ()
49         {
50             return m_outEncoding;
51         }
52
53         public void setOutDir (final File JavaDoc outDir)
54         {
55             if ($assert.ENABLED) $assert.ASSERT (outDir != null, "null input: outDir");
56             
57             m_outDir = outDir;
58         }
59
60         public File JavaDoc getOutDir ()
61         {
62             return m_outDir;
63         }
64
65         public void setOutFile (final File JavaDoc outFile)
66         {
67             if ($assert.ENABLED) $assert.ASSERT (outFile != null, "null input: outFile");
68             
69             m_outFile = outFile;
70         }
71
72         public File JavaDoc getOutFile ()
73         {
74             return m_outFile;
75         }
76
77         public void setUnitsType (final int unitsType)
78         {
79             if ($assert.ENABLED) $assert.ASSERT (unitsType >= IItemAttribute.UNITS_COUNT && unitsType <= IItemAttribute.UNITS_INSTR, "invalid units type: " + unitsType);
80             
81             m_unitsType = unitsType;
82         }
83
84         public int getUnitsType ()
85         {
86             return m_unitsType;
87         }
88
89         public void setViewType (final int viewType)
90         {
91             if ($assert.ENABLED) $assert.ASSERT (viewType >= IReportDataView.HIER_CLS_VIEW && viewType <= IReportDataView.HIER_SRC_VIEW, "invalid view type: " + viewType);
92             
93             m_viewType = viewType;
94         }
95
96         public int getViewType ()
97         {
98             return m_viewType;
99         }
100
101         public void setDepth (final int depth)
102         {
103             if ($assert.ENABLED) $assert.ASSERT (depth >= IItemMetadata.TYPE_ID_ALL && depth <= IItemMetadata.TYPE_ID_METHOD, "invalid depth: " + depth);
104             
105             m_depth = depth;
106         }
107
108         public int getDepth()
109         {
110             return m_depth;
111         }
112
113         public void setHideClasses (final boolean hideClasses)
114         {
115             m_hideClasses = hideClasses;
116         }
117
118         public boolean getHideClasses ()
119         {
120             return m_hideClasses;
121         }
122
123         public void setColumnOrder (final int [] columnOrder)
124         {
125             if ($assert.ENABLED) $assert.ASSERT (columnOrder != null && columnOrder.length != 0, "null/empty input: outEncoding");
126             
127             m_columnOrder = columnOrder;
128         }
129
130         public int [] getColumnOrder ()
131         {
132             return m_columnOrder;
133         }
134
135         public void setSortOrder (final int [] sortOrder)
136         {
137             if ($assert.ENABLED) $assert.ASSERT (sortOrder != null, "null input: sortOrder");
138             
139             m_sortOrder = sortOrder;
140         }
141
142         public int [] getSortOrder ()
143         {
144             return m_sortOrder;
145         }
146
147         public void setMetrics (final IntIntMap metrics)
148         {
149             if ($assert.ENABLED) $assert.ASSERT (metrics != null, "null input: metrics");
150             
151             m_metrics = metrics;
152         }
153
154         public IntIntMap getMetrics ()
155         {
156             return m_metrics;
157         }
158         
159         // TODO: toString/logging
160

161         void validate () throws IllegalArgumentException JavaDoc
162         {
163             if ($assert.ENABLED)
164             {
165                 $assert.ASSERT (m_outEncoding != null, "m_outEncoding not set");
166                 $assert.ASSERT (m_outDir != null || m_outFile != null, "either m_outDir or m_outFile must be set");
167                 $assert.ASSERT (m_columnOrder != null, "m_columnOrder not set");
168                 $assert.ASSERT (m_sortOrder != null, "m_sortOrder not set");
169                 $assert.ASSERT (m_metrics != null, "m_metrics not set");
170             }
171         }
172
173
174         private String JavaDoc m_outEncoding;
175         private File JavaDoc m_outDir;
176         private File JavaDoc m_outFile;
177         
178         private int m_unitsType;
179         private int m_viewType;
180         
181         private boolean m_hideClasses;
182         private int m_depth;
183         
184         // TODO: fraction/number format strings...
185

186         private int [] m_columnOrder; // attribute IDs [order indicates column order]
187
private int [] m_sortOrder; // if m_sortOrder[i+1]>0 , sort m_columnOrder[m_sortOrder[i]] in ascending order
188
private IntIntMap m_metrics; // pass criteria (column attribute ID -> metric)
189

190     } // end of nested class
191

192     
193 // /**
194
// * Creates a property view specific to 'reportType' report type.
195
// *
196
// * @param appProperties
197
// * @param reportType
198
// * @return
199
// */
200
// public static Properties getReportProperties (final Properties appProperties, final String reportType)
201
// {
202
// if ((reportType == null) || (reportType.length () == 0))
203
// throw new IllegalArgumentException ("null/empty input: reportType");
204
//
205
// if (appProperties == null) return new XProperties ();
206
//
207
// return new ReportPropertyLookup (appProperties, reportType);
208
// }
209

210     
211 // /**
212
// * @param type [null/empty indicates type-neutral property]
213
// */
214
// public static String getReportProperty (final String type, final Map properties, final String key)
215
// {
216
// if (properties == null) throw new IllegalArgumentException ("null input: properties");
217
// if (key == null) throw new IllegalArgumentException ("null input: key");
218
//
219
// String fullKey;
220
//
221
// if ((type == null) || (type.length () == 0))
222
// fullKey = IReportParameters.PREFIX.concat (key);
223
// else
224
// {
225
// fullKey = IReportParameters.PREFIX.concat (type).concat (".").concat (key);
226
//
227
// if (! properties.containsKey (fullKey)) // default to type-neutral lookup
228
// fullKey = IReportParameters.PREFIX.concat (key);
229
// }
230
//
231
// return (String) properties.get (fullKey);
232
// }
233
//
234
// public static String getReportParameter (final String type, final Map properties, final String key, final String def)
235
// {
236
// final String value = getReportProperty (type, properties, key);
237
//
238
// return (value == null) ? def : value;
239
// }
240

241     
242     public static ParsedProperties parseProperties (final IProperties properties, final String JavaDoc type)
243     {
244         if ($assert.ENABLED) $assert.ASSERT (properties != null, "properties = null");
245         
246         final ParsedProperties result = new ParsedProperties ();
247         {
248             result.setOutEncoding (getReportProperty (properties, type, IReportProperties.OUT_ENCODING, false));
249         }
250         
251         // TODO: outDirName is no longer supported
252

253         {
254             final String JavaDoc outDirName = getReportProperty (properties, type, IReportProperties.OUT_DIR, true);
255             final String JavaDoc outFileName = getReportProperty (properties, type, IReportProperties.OUT_FILE, false);
256     
257             // renormalize the out dir and file combination:
258

259             if (outFileName != null)
260             {
261                 final File JavaDoc fullOutFile = Files.newFile (outDirName, outFileName);
262                 
263                 final File JavaDoc dir = fullOutFile.getParentFile ();
264                 if (dir != null) result.setOutDir (dir);
265             
266                 result.setOutFile (new File JavaDoc (fullOutFile.getName ()));
267             }
268             else if (outDirName != null)
269             {
270                 result.setOutDir (new File JavaDoc (outDirName));
271             }
272         }
273
274         {
275             final String JavaDoc unitsType = getReportProperty (properties, type, IReportProperties.UNITS_TYPE, true, IReportProperties.DEFAULT_UNITS_TYPE);
276             result.setUnitsType (IReportProperties.COUNT_UNITS.equals (unitsType) ? IItemAttribute.UNITS_COUNT : IItemAttribute.UNITS_INSTR);
277             
278             // TODO: invalid setting not checked
279
}
280         {
281             /* view type is no longer a user-overridable property [it is driven by SourceFile attribute presence]
282
283             final String viewType = getReportProperty (properties, type, IReportProperties.VIEW_TYPE, IReportProperties.DEFAULT_VIEW_TYPE);
284             result.setViewType (IReportProperties.SRC_VIEW.equals (viewType) ? IReportDataView.HIER_SRC_VIEW : IReportDataView.HIER_CLS_VIEW);
285             */

286             
287             result.setViewType (IReportDataView.HIER_SRC_VIEW);
288         }
289         
290         {
291             final String JavaDoc hideClasses = getReportProperty (properties, type, IReportProperties.HIDE_CLASSES, true, IReportProperties.DEFAULT_HIDE_CLASSES);
292             result.setHideClasses (Property.toBoolean (hideClasses));
293         
294             // TODO: log this
295
if (result.getViewType () == IReportDataView.HIER_CLS_VIEW)
296                 result.setHideClasses (false);
297         }
298         {
299             final String JavaDoc depth = getReportProperty (properties, type, IReportProperties.DEPTH, false, IReportProperties.DEFAULT_DEPTH);
300             
301             if (IReportProperties.DEPTH_ALL.equals (depth))
302                 result.setDepth (AllItem.getTypeMetadata ().getTypeID ());
303             else if (IReportProperties.DEPTH_PACKAGE.equals (depth))
304                 result.setDepth (PackageItem.getTypeMetadata ().getTypeID ());
305             else if (IReportProperties.DEPTH_SRCFILE.equals (depth))
306                 result.setDepth (SrcFileItem.getTypeMetadata ().getTypeID ());
307             else if (IReportProperties.DEPTH_CLASS.equals (depth))
308                 result.setDepth (ClassItem.getTypeMetadata ().getTypeID ());
309             else if (IReportProperties.DEPTH_METHOD.equals (depth))
310                 result.setDepth (MethodItem.getTypeMetadata ().getTypeID ());
311             else
312                 // TODO: properly prefixes prop name
313
throw new EMMARuntimeException (INVALID_PARAMETER_VALUE, new Object JavaDoc [] {IReportProperties.DEPTH, depth});
314         }
315         
316         if (result.getHideClasses () &&
317            (result.getViewType () == IReportDataView.HIER_SRC_VIEW) &&
318            (result.getDepth () == IItemMetadata.TYPE_ID_CLASS))
319         {
320             result.setDepth (IItemMetadata.TYPE_ID_SRCFILE);
321         }
322         
323         final Set JavaDoc /* String */ columnNames = new HashSet JavaDoc ();
324         {
325             final String JavaDoc columnList = getReportProperty (properties, type, IReportProperties.COLUMNS, false, IReportProperties.DEFAULT_COLUMNS);
326             final IntVector _columns = new IntVector ();
327             
328             final int [] out = new int [1];
329             
330             for (StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc (columnList, ","); tokenizer.hasMoreTokens (); )
331             {
332                 final String JavaDoc columnName = tokenizer.nextToken ().trim ();
333                 if (! COLUMNS.get (columnName, out))
334                 {
335                     // TODO: generate the entire enum list in the err msg
336
throw new EMMARuntimeException (INVALID_COLUMN_NAME, new Object JavaDoc [] {columnName});
337                 }
338                 
339                 if (! REMOVE_DUPLICATE_COLUMNS || ! columnNames.contains (columnName))
340                 {
341                     columnNames.add (columnName);
342                     _columns.add (out [0]);
343                 }
344             }
345             
346             result.setColumnOrder (_columns.values ());
347         }
348         // [assertion: columnNames contains all columns for the report (some
349
// may get removed later by individual report generators if some debug info
350
// is missing)]
351

352         {
353             final String JavaDoc sortList = getReportProperty (properties, type, IReportProperties.SORT, false, IReportProperties.DEFAULT_SORT);
354             final IntVector _sort = new IntVector ();
355             
356             final int [] out = new int [1];
357             
358             for (StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc (sortList, ","); tokenizer.hasMoreTokens (); )
359             {
360                 final String JavaDoc sortSpec = tokenizer.nextToken ().trim ();
361                 final String JavaDoc columnName;
362                 final int dir;
363                 
364                 switch (sortSpec.charAt (0))
365                 {
366                     case IReportProperties.ASC:
367                     {
368                         dir = +1;
369                         columnName = sortSpec.substring (1);
370                     }
371                     break;
372                     
373                     case IReportProperties.DESC:
374                     {
375                         dir = -1;
376                         columnName = sortSpec.substring (1);
377                     }
378                     break;
379                     
380                     default:
381                     {
382                         dir = +1;
383                         columnName = sortSpec;
384                     }
385                     break;
386                     
387                 } // end of switch
388

389                 // silently ignore columns not in the column list:
390
if (columnNames.contains (columnName))
391                 {
392                     COLUMNS.get (columnName, out);
393                     
394                     _sort.add (out [0]); // sort attribute ID
395
_sort.add (dir); // sort direction
396
}
397                 
398                 result.setSortOrder (_sort.values ());
399             }
400         }
401         {
402             final String JavaDoc metricList = getReportProperty (properties, type, IReportProperties.METRICS, true, IReportProperties.DEFAULT_METRICS);
403             final IntIntMap _metrics = new IntIntMap ();
404             
405             final int [] out = new int [1];
406             
407             // TODO: perhaps should throw on invalid input here
408
for (StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc (metricList, ","); tokenizer.hasMoreTokens (); )
409             {
410                 final String JavaDoc metricSpec = tokenizer.nextToken ().trim ();
411                 final String JavaDoc columnName;
412                 final double criterion;
413                 
414                 final int separator = metricSpec.indexOf (IReportProperties.MSEPARATOR);
415                 if (separator > 0) // silently ignore invalid entries
416
{
417                     // silently ignore invalid cutoff values:
418
try
419                     {
420                         criterion = Double.parseDouble (metricSpec.substring (separator + 1));
421                         if ((criterion < 0.0) || (criterion > 101.0)) continue;
422                     }
423                     catch (NumberFormatException JavaDoc nfe)
424                     {
425                         nfe.printStackTrace (System.out);
426                         continue;
427                     }
428                     
429                     columnName = metricSpec.substring (0, separator);
430                     
431                     // silently ignore columns not in the column list:
432
if (columnNames.contains (columnName))
433                     {
434                         COLUMNS.get (columnName, out);
435                     
436                         _metrics.put (out [0], (int) Math.round (((criterion * IItem.PRECISION) / 100.0)));
437                     }
438                 }
439             }
440                                         
441             result.setMetrics (_metrics);
442         }
443         
444         result.validate ();
445         
446         return result;
447     }
448
449     
450     // protected: .............................................................
451

452     // package: ...............................................................
453

454     // private: ...............................................................
455

456     
457     private static final class ReportPropertyMapper implements IProperties.IMapper
458     {
459         public String JavaDoc getMappedKey (final String JavaDoc key)
460         {
461             if (key != null)
462             {
463                 if (key.startsWith (IReportProperties.PREFIX))
464                 {
465                     final int secondDot = key.indexOf ('.', IReportProperties.PREFIX.length ());
466                     if (secondDot > 0)
467                     {
468                         // TODO: make this more precise (actually check the report type value string)
469

470                         return IReportProperties.PREFIX.concat (key.substring (secondDot + 1));
471                     }
472                 }
473             }
474             
475             return null;
476         }
477
478     } // end of nested class
479

480     
481 // private static final class ReportPropertyLookup extends XProperties
482
// {
483
// // note: due to incredibly stupid coding in java.util.Properties
484
// // (getProperty() uses a non-virtual call to super.get(), while propertyNames()
485
// // uses a virtual call to the same method instead of delegating to getProperty())
486
// // I must override both methods below
487
//
488
// public String getProperty (String key)
489
// {
490
// return (String) get (key);
491
// }
492
//
493
// // TODO: this kind of lookup makes the property listing confusing
494
//
495
// public Object get (final Object _key)
496
// {
497
// if (! (_key instanceof String)) return null;
498
//
499
// String key = (String) _key;
500
//
501
// if (key.startsWith (IReportProperties.PREFIX))
502
// key = key.substring (IReportProperties.PREFIX.length ());
503
//
504
// if (key.startsWith (m_reportType))
505
// key = key.substring (m_reportType.length () + 1);
506
//
507
// String fullKey = IReportProperties.PREFIX.concat (m_reportType).concat (".").concat (key);
508
//
509
// String result = defaults.getProperty (fullKey, null);
510
// if (result != null) return result;
511
//
512
// // fall back to report type-neutral namespace:
513
// fullKey = IReportProperties.PREFIX.concat (key);
514
//
515
// result = defaults.getProperty (fullKey, null);
516
// if (result != null) return result;
517
//
518
// return null;
519
// }
520
//
521
//
522
// ReportPropertyLookup (final Properties appProperties, final String reportType)
523
// {
524
// super (appProperties);
525
//
526
// m_reportType = reportType;
527
// }
528
//
529
//
530
// private final String m_reportType; // never null or empty [factory-ensured]
531
//
532
// } // end of nested class
533

534     
535     private ReportProperties () {} // prevent subclassing
536

537     
538     private static String JavaDoc getReportProperty (final IProperties properties, final String JavaDoc type, final String JavaDoc key, final boolean allowBlank)
539     {
540         return getReportProperty (properties, type, key, allowBlank, null);
541     }
542     
543     private static String JavaDoc getReportProperty (final IProperties properties, final String JavaDoc type, final String JavaDoc key, final boolean allowBlank, final String JavaDoc dflt)
544     {
545         if ($assert.ENABLED) $assert.ASSERT (properties != null, "null input: properties");
546         if ($assert.ENABLED) $assert.ASSERT (key != null, "null input: key");
547         
548         final String JavaDoc result = properties.getProperty (IReportProperties.PREFIX.concat (type).concat (".").concat (key), dflt);
549         
550         if (! allowBlank && (result != null) && (result.trim ().length () == 0))
551             return dflt;
552         else
553             return result;
554     }
555
556     
557     private static final boolean REMOVE_DUPLICATE_COLUMNS = true;
558     private static final ObjectIntMap /* col name:String -> metadata:IItemMetadata */ COLUMNS; // set in <clinit>
559

560     static
561     {
562         REPORT_PROPERTY_MAPPER = new ReportPropertyMapper ();
563         
564         final ObjectIntMap columns = new ObjectIntMap ();
565         
566         columns.put (IReportProperties.ITEM_NAME_COLUMN, IItemAttribute.ATTRIBUTE_NAME_ID);
567         columns.put (IReportProperties.CLASS_COVERAGE_COLUMN, IItemAttribute.ATTRIBUTE_CLASS_COVERAGE_ID);
568         columns.put (IReportProperties.METHOD_COVERAGE_COLUMN, IItemAttribute.ATTRIBUTE_METHOD_COVERAGE_ID);
569         columns.put (IReportProperties.BLOCK_COVERAGE_COLUMN, IItemAttribute.ATTRIBUTE_BLOCK_COVERAGE_ID);
570         columns.put (IReportProperties.LINE_COVERAGE_COLUMN, IItemAttribute.ATTRIBUTE_LINE_COVERAGE_ID);
571         
572         COLUMNS = columns;
573     }
574
575 } // end of class
576
// ----------------------------------------------------------------------------
Popular Tags