KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jimm > datavision > ReportReader


1 package jimm.datavision;
2 import jimm.datavision.field.*;
3 import jimm.datavision.source.*;
4 import jimm.datavision.source.sql.*;
5 import jimm.datavision.source.charsep.CharSepSource;
6 import jimm.datavision.source.ncsql.NCDatabase;
7 import jimm.util.I18N;
8 import java.io.*;
9 import java.util.*;
10 import java.awt.Color JavaDoc;
11
12 import javax.xml.parsers.SAXParserFactory JavaDoc;
13
14 import org.xml.sax.*;
15 import org.xml.sax.helpers.DefaultHandler JavaDoc;
16
17 /**
18  * A report reader reads an XML file and creates the innards of a report.
19  *
20  * @author Jim Menard, <a HREF="mailto:jimm@io.com">jimm@io.com</a>
21  */

22 public class ReportReader extends DefaultHandler JavaDoc {
23
24 // ================================================================
25
/**
26  * This class is used when we are converting formulas from the old
27  * pre-DTD_VERSION_FORMULA_IDS format to the new format.
28  * <p>
29  * We store a copy of the original eval string because if we were to
30  * retrieve it from the formula by calling
31  * <code>Formula.getEvalString</code>, the formula would attempt to start
32  * observing other formulas within the eval string. This would not work
33  * because those formulas are represented the old way (by name instead of
34  * id) and thus the code that looks for those formulas in order to observe
35  * them fails. We don't have to clone the eval string, just save a
36  * reference to it.
37  */

38 static class FormulaConversion {
39 Formula formula;
40 String JavaDoc expression;
41 FormulaConversion(Formula f, String JavaDoc expr) {
42     formula = f;
43     expression = expr;
44 }
45 }
46 // ================================================================
47

48 /**
49  * If there is no report element dtd-version attribute, this is the default
50  * value to use. That's because DataVision XML files before version 0.2
51  * didn't include version numbers.
52  */

53 protected static final double DEFAULT_DTD_VERSION = 0.2;
54
55 /**
56  * This is the DTD version where formula ids were introduced. Versions
57  * before this one require runtime conversion.
58  */

59 protected static final double DTD_VERSION_FORMULA_IDS = 0.2;
60
61 protected Stack tagNameStack;
62 protected Report report;
63 protected Subreport subreport;
64 protected Parameter parameter;
65 protected Formula formula;
66 protected UserColumn usercol;
67 protected Section section;
68 protected Group group;
69 protected Field field;
70 protected String JavaDoc textData;
71 protected Border border;
72 protected Line line;
73 protected double dtdVersion;
74 protected HashMap formulasToConvert;
75 protected int nextSectionLocation;
76 protected boolean missingColumnSeen;
77 protected boolean inSubreportJoins;
78
79 /**
80  * Constructor.
81  *
82  * @param report the report we are building
83  */

84 public ReportReader(Report report) {
85     this.report = report;
86     tagNameStack = new Stack();
87     dtdVersion = DEFAULT_DTD_VERSION;
88 }
89
90 /**
91  * Uses the InputSource to find the XML, reads it, and builds the innards
92  * of the report. To specify a URL, use <code>new
93  * InputSource("http://...")</code>.
94  *
95  * @param in the input source
96  */

97 public void read(InputSource in) throws Exception JavaDoc {
98     removeReportSections();
99     SAXParserFactory.newInstance().newSAXParser().parse(in, this);
100     postParse();
101 }
102
103 /**
104  * Reads an XML file and builds the innards of the report.
105  *
106  * @param f the XML file
107  */

108 public void read(File f) throws Exception JavaDoc {
109     removeReportSections();
110     SAXParserFactory.newInstance().newSAXParser().parse(f, this);
111     postParse();
112 }
113
114 /**
115  * Removes the report sections that are created when a report is created.
116  */

117 protected void removeReportSections() {
118     getReport().headers().clear();
119     getReport().pageHeaders().clear();
120     getReport().pageFooters().clear();
121     getReport().footers().clear();
122     getReport().details().clear();
123 }
124
125 /**
126  * Performed after a parse, we convert old-style formulas if necessary and
127  * ensure that certain report sections are non-empty.
128  */

129 protected void postParse() throws SAXException {
130     convertFormulas();
131
132     // Headers, footers, and details must have at least one section.
133
ensureNotEmpty(report.headers());
134     ensureNotEmpty(report.pageHeaders());
135     ensureNotEmpty(report.details());
136     ensureNotEmpty(report.footers());
137     ensureNotEmpty(report.pageFooters());
138
139     for (Iterator iter = report.subreports(); iter.hasNext(); )
140       ensureNotEmpty(((Subreport)iter.next()).details());
141 }
142
143 /**
144  * Ensures that the specified collection of sections is not empty. If we
145  * do create a section, it is marked as suppressed.
146  *
147  * @param area collection of sections
148  * sections
149  */

150 protected void ensureNotEmpty(SectionArea area) {
151     if (area.isEmpty()) {
152     Section s = new Section(report);
153     s.getSuppressionProc().setHidden(true);
154     area.add(s);
155     }
156 }
157
158 protected Report getReport() {
159     return subreport != null ? subreport : report;
160 }
161
162 public void startElement(final String JavaDoc namespaceURI, final String JavaDoc localName,
163              final String JavaDoc qName, final Attributes attributes)
164     throws SAXException
165 {
166     String JavaDoc tagName = localName;
167     if (tagName == null || tagName.length() == 0)
168         tagName = qName;
169
170     String JavaDoc parentTag = tagNameStack.empty() ? null
171     : (String JavaDoc)tagNameStack.peek();
172     tagNameStack.push(new String JavaDoc(tagName));
173
174     // Get ready to start collecting text
175
if (textData == null || textData.length() > 0)
176     textData = new String JavaDoc();
177
178     if ("report".equals(tagName)) report(attributes);
179     else if ("bean-scripting-framework".equals(tagName))
180     defaultLanguage(attributes);
181     else if ("language".equals(tagName)) language(attributes);
182     else if ("database".equals(tagName)) database(attributes);
183     else if ("query".equals(tagName)) query(attributes);
184     else if ("charsep".equals(tagName)) charSepSource(attributes);
185     else if ("nc-database".equals(tagName)) ncDatabaseSource(attributes);
186     else if ("column".equals(tagName)) column(attributes);
187     else if ("subreport-joins".equals(tagName)) inSubreportJoins = true;
188     else if ("join".equals(tagName)) join(attributes);
189     else if ("sort".equals(tagName)) sort(attributes);
190     else if ("subreport".equals(tagName)) subreport(attributes);
191     else if ("parameter".equals(tagName)) parameter(attributes);
192     else if ("formula".equals(tagName)) formula(parentTag, attributes);
193     else if ("usercol".equals(tagName)) usercol(attributes);
194     else if ("headers".equals(tagName)) header(parentTag);
195     else if ("footers".equals(tagName)) footer(parentTag);
196     else if ("group".equals(tagName)) group(attributes);
197     else if ("details".equals(tagName))
198     nextSectionLocation = SectionArea.DETAIL;
199     else if ("section".equals(tagName)) section(attributes);
200     else if ("field".equals(tagName)) field(attributes);
201     else if ("bounds".equals(tagName)) bounds(attributes);
202     else if ("edge".equals(tagName)) edge(attributes);
203     else if ("format".equals(tagName)) format(attributes);
204     else if ("border".equals(tagName)) border(attributes);
205     else if ("line".equals(tagName)) line(attributes);
206     else if ("point".equals(tagName)) point(attributes);
207     else if ("paper".equals(tagName)) paper(attributes);
208     else if ("suppression-proc".equals(tagName)) suppressionProc(attributes);
209 }
210
211 protected void header(String JavaDoc parentTag) {
212     if ("report".equals(parentTag))
213     nextSectionLocation = SectionArea.REPORT_HEADER;
214     else if ("page".equals(parentTag))
215     nextSectionLocation = SectionArea.PAGE_HEADER;
216     else if ("group".equals(parentTag))
217     nextSectionLocation = SectionArea.GROUP_HEADER;
218 }
219
220 protected void footer(String JavaDoc parentTag) {
221     if ("report".equals(parentTag))
222     nextSectionLocation = SectionArea.REPORT_FOOTER;
223     else if ("page".equals(parentTag))
224     nextSectionLocation = SectionArea.PAGE_FOOTER;
225     else if ("group".equals(parentTag))
226     nextSectionLocation = SectionArea.GROUP_FOOTER;
227 }
228
229 /**
230  * Handle elements expecting text data.
231  */

232 public void endElement(final String JavaDoc namespaceURI, final String JavaDoc localName,
233                final String JavaDoc qName)
234     throws SAXException
235 {
236     String JavaDoc tagName = localName;
237     if (tagName == null || tagName.length() == 0)
238         tagName = qName;
239
240     // If we were paranoid, we could compare tagName to the top of the
241
// stack. Let's not.
242
tagNameStack.pop();
243
244     if ("description".equals(tagName))
245     getReport().setDescription(textData);
246     else if ("subreport".equals(tagName))
247     subreport = null;
248     else if ("subreport-joins".equals(tagName))
249     inSubreportJoins = false;
250     else if ("default".equals(tagName) && parameter != null)
251     parameter.addDefaultValue(textData);
252     else if ("formula".equals(tagName)) {
253     formula.setExpression(textData);
254     // If we need to convert this formula later, save a copy of
255
// this eval string text.
256
if (formulasToConvert != null) {
257         FormulaConversion fc =
258         (FormulaConversion)formulasToConvert.get(formula.getName());
259         if (fc != null)
260         fc.expression = new String JavaDoc(textData);
261     }
262     formula = null;
263     }
264     else if ("usercol".equals(tagName)) {
265     usercol.setExpression(textData);
266     usercol = null;
267     }
268     else if ("text".equals(tagName) && field != null)
269     field.setValue(textData);
270     else if ("where".equals(tagName))
271     getReport().getDataSource().getQuery().setWhereClause(textData);
272     else if ("metadata-url".equals(tagName)) {
273         try {
274             getReport().getDataSource().readMetadataFrom(textData);
275     }
276         catch (Exception JavaDoc e) {
277         throw new SAXException(e);
278         }
279     }
280 }
281
282 /**
283  * Reads text data. Text data inside a single tag can be broken up into
284  * multiple calls to this method.
285  */

286 public void characters(char ch[], int start, int length) {
287     textData += new String JavaDoc(ch, start, length);
288 }
289
290 /**
291  * Reads the report tag.
292  */

293 protected void report(Attributes attributes) {
294     String JavaDoc dtdVersionString = attributes.getValue("dtd-version");
295     dtdVersion = (dtdVersionString == null)
296     ? DEFAULT_DTD_VERSION : Double.parseDouble(dtdVersionString);
297
298     getReport().setName(attributes.getValue("name"));
299     getReport().setTitle(attributes.getValue("title"));
300     getReport().setAuthor(attributes.getValue("author"));
301 }
302
303 protected void defaultLanguage(Attributes attributes) {
304     String JavaDoc lang = rubyLanguageNameHack(attributes.getValue("default-language"));
305     getReport().getScripting().setDefaultLanguage(lang);
306 }
307
308 protected void language(Attributes attributes) {
309     String JavaDoc lang = rubyLanguageNameHack(attributes.getValue("name"));
310     getReport().getScripting().addLanguage(lang, attributes.getValue("class"));
311 }
312
313 protected String JavaDoc rubyLanguageNameHack(String JavaDoc lang) {
314     // Hack: Scripting.java had the default value of "ruby" originally,
315
// and I've changed it to "Ruby".
316
return "ruby".equals(lang) ? "Ruby" : lang;
317 }
318
319 /**
320  * Reads the database tag and creates the database object. If the report
321  * already has a data source (for example, someone has called
322  * <code>Report.setDataSource</code> or
323  * <code>Report.setDatabaseConnection</code>), then we don't do anything.
324  *
325  * @see Report#hasDataSource
326  * @see Report#setDatabaseConnection
327  */

328 protected void database(Attributes attributes) {
329     if (getReport().hasDataSource())
330     return;
331
332     try {
333     Database db = new Database(attributes.getValue("driverClassName"),
334                    attributes.getValue("connInfo"),
335                    getReport(),
336                    attributes.getValue("name"),
337                    attributes.getValue("username"));
338     getReport().setDataSource(db);
339     }
340     catch (UserCancellationException iae) {
341     // Thrown by dataSource when user cancelled password dialog.
342
// Let the report catch this.
343
throw iae;
344     }
345     catch (Exception JavaDoc e) {
346     ErrorHandler.error(I18N.get("ReportReader.db_err"), e,
347                I18N.get("ReportReader.db_err_title"));
348     }
349 }
350
351 /**
352  * Reads the query. Nothing to do, since the data source already has an
353  * empty query.
354  */

355 protected void query(Attributes attributes) {
356 }
357
358 /**
359  * Reads and creates a CharSepSource.
360  */

361 protected void charSepSource(Attributes attributes) {
362     if (getReport().hasDataSource())
363     return;
364
365     CharSepSource charSepSource = new CharSepSource(getReport());
366     String JavaDoc charString = attributes.getValue("sep-char");
367     if (charString != null)
368     charSepSource.setSepChar(charString.charAt(0));
369
370     getReport().setDataSource(charSepSource);
371 }
372
373 /**
374  * Reads and creates an NCDatabase data source.
375  */

376 protected void ncDatabaseSource(Attributes attributes) {
377     if (!getReport().hasDataSource())
378     getReport().setDataSource(new NCDatabase(getReport()));
379 }
380
381 protected void column(Attributes attributes) {
382     String JavaDoc name = attributes.getValue("name");
383     int type = Column.typeFromString(attributes.getValue("type"));
384     Column col = new Column(name, name, type);
385     col.setDateParseFormat(attributes.getValue("date-format"));
386
387     getReport().getDataSource().addColumn(col);
388 }
389
390 protected void join(Attributes attributes) {
391     Column from = findColumn(attributes.getValue("from"));
392     Column to = findColumn(attributes.getValue("to"));
393     if (from != null && to != null) {
394     Join join = new Join(from, attributes.getValue("relation"), to);
395     if (inSubreportJoins)
396         ((Subreport)getReport()).addJoin(join);
397     else
398         getReport().getDataSource().getQuery().addJoin(join);
399     }
400 }
401
402 protected void sort(Attributes attributes) {
403     String JavaDoc oldColumnIdStr = attributes.getValue("column");
404     Selectable selectable = null;
405     if (oldColumnIdStr != null) { // Old-style column id attribute
406
selectable = findColumn(oldColumnIdStr.trim());
407     if (selectable == null) {
408         group = null;
409         return;
410     }
411     }
412     else {
413     selectable =
414         findSelectable(attributes.getValue("groupable-id").trim(),
415               attributes.getValue("groupable-type").trim());
416     }
417
418     if (selectable != null) {
419     String JavaDoc str = attributes.getValue("order");
420     int val = (str != null && str.length() > 0 && str.charAt(0) == 'd')
421         ? Query.SORT_DESCENDING : Query.SORT_ASCENDING;
422     getReport().getDataSource().getQuery().addSort(selectable, val);
423     }
424 }
425
426 protected void subreport(Attributes attributes) {
427     subreport = new Subreport(report, new Long JavaDoc(attributes.getValue("id")));
428     // The subreport adds itself to the parent report.
429

430     removeReportSections(); // Acts on subreport
431

432     try {
433     Database db = (Database)report.getDataSource();
434     subreport.setDataSource(new SubreportDatabase(db.getConnection(),
435                               subreport));
436     }
437     catch (Exception JavaDoc e) {
438     ErrorHandler.error(I18N.get("ReportReader.db_err"), e,
439                I18N.get("ReportReader.db_err_title"));
440     }
441 }
442
443 protected void parameter(Attributes attributes) throws SAXException {
444     parameter = new Parameter(new Long JavaDoc(attributes.getValue("id")),
445                   getReport(),
446                   attributes.getValue("type"),
447                   attributes.getValue("name"),
448                   attributes.getValue("question"),
449                   attributes.getValue("arity"));
450     getReport().addParameter(parameter);
451 }
452
453 /**
454  * Reads a formula. If the XML format is really old, we need to give
455  * each formula an id number and translate its formula text so references
456  * to other formulas use the other formula's id number instead of its name.
457  */

458 protected void formula(String JavaDoc parentTag, Attributes attributes)
459     throws SAXException
460 {
461     String JavaDoc idString = attributes.getValue("id");
462     String JavaDoc name = attributes.getValue("name");
463     Long JavaDoc id = null;
464     if (idString == null) {
465     if (dtdVersion >= DTD_VERSION_FORMULA_IDS) {
466         String JavaDoc str = I18N.get("ReportReader.the_formula")
467         + ' ' + name + ' '
468         + I18N.get("ReportReader.formula_missing_id_err");
469         throw new SAXException(str);
470     }
471     // else, we are OK with a null id
472
}
473     else
474     id = new Long JavaDoc(idString);
475
476     if ("formulas".equals(parentTag)) {
477     formula = new Formula(id, getReport(), name, null);
478     getReport().addFormula(formula);
479     }
480     else if ("suppression-proc".equals(parentTag)) {
481     // We don't use a new formula; we use the one the section has.
482
formula = section.getSuppressionProc().getFormula();
483     }
484     else {
485     formula = new Formula(id, getReport(), name, null);
486     getReport().setStartFormula(formula);
487     }
488
489     // If the id is null, that means we need to convert this formula
490
// to the current format.
491
if (id == null) {
492     if (formulasToConvert == null)
493         formulasToConvert = new HashMap();
494     FormulaConversion fc = new FormulaConversion(formula, null);
495     formulasToConvert.put(formula.getName(), fc);
496     }
497
498     String JavaDoc language = attributes.getValue("language");
499     if (language != null)
500     formula.setLanguage(language);
501 }
502
503 /**
504  * Reads a user column. Value of user column will be read later.
505  */

506 protected void usercol(Attributes attributes) throws SAXException {
507     usercol = new UserColumn(new Long JavaDoc(attributes.getValue("id")), getReport(),
508                  attributes.getValue("name"), null);
509     getReport().addUserColumn(usercol);
510 }
511
512 /**
513  * Revisits each formula and let it convert formula names to
514  * formula id numbers within its eval string.
515  */

516 protected void convertFormulas() throws SAXException {
517     if (formulasToConvert != null) {
518     for (Iterator iter = formulasToConvert.values().iterator();
519          iter.hasNext(); )
520     {
521         FormulaConversion fc = (FormulaConversion)iter.next();
522         Formula f = fc.formula;
523         try {
524         f.setEditableExpression(fc.expression);
525         }
526         catch (IllegalArgumentException JavaDoc iae) {
527         String JavaDoc msg = I18N.get("ReportReader.the_formula")
528             + ' ' + f.getName() + ' '
529             + I18N.get("ReportReader.formula_unknown_name");
530         throw new SAXException(msg);
531         }
532     }
533     }
534 }
535
536 /** Creates a group and adds it to the report. */
537 protected void group(Attributes attributes) {
538     String JavaDoc oldColumnIdStr = attributes.getValue("column");
539     Selectable selectable = null;
540     if (oldColumnIdStr != null) { // Old-style column id attribute
541
selectable = findColumn(oldColumnIdStr.trim());
542     if (selectable == null) {
543         group = null;
544         return;
545     }
546     }
547     else {
548     selectable =
549         findSelectable(attributes.getValue("groupable-id").trim(),
550                attributes.getValue("groupable-type").trim());
551     }
552
553     group = new Group(getReport(), selectable);
554
555     String JavaDoc sortOrderString = attributes.getValue("sort-order"); // OK if null
556
if (sortOrderString != null)
557     group.setSortOrder(Group.sortOrderStringToInt(sortOrderString.trim()));
558
559     getReport().groups.add(group);
560 }
561
562 /** Creates an empty section and adds it to the report. */
563 protected void section(Attributes attributes) {
564     section = new Section(getReport());
565     section.setMinHeight(Double.parseDouble(attributes.getValue("height")));
566
567     // Handle old XML files that store a "suppressed" attribute.
568
String JavaDoc boolValString = attributes.getValue("suppressed");
569     if ("true".equals(boolValString))
570     section.getSuppressionProc().setHidden(true);
571
572     boolValString = attributes.getValue("pagebreak");
573     section.setPageBreak("true".equals(boolValString));
574
575     addSectionToReport();
576 }
577
578 /**
579  * Adds the last seen section to the report. The value of
580  * <code>nextSectionLocation</code> determines where the section belongs.
581  */

582 protected void addSectionToReport() {
583     switch (nextSectionLocation) {
584     case SectionArea.GROUP_HEADER:
585     if (group != null)
586         group.headers().add(section);
587     break;
588     case SectionArea.GROUP_FOOTER:
589     if (group != null)
590         group.footers().add(section);
591     break;
592     default:
593     getReport().getSectionArea(nextSectionLocation).add(section);
594     break;
595     }
596 }
597
598 /**
599  * Reads and creates a field. If the XML format is really old, we need to
600  * convert formula fields by changing their values from the formula name
601  * to the formula id.
602  */

603 protected void field(Attributes attributes) {
604     if (section == null) { // We're reading the report's default field
605
field = report.getDefaultField();
606     return;
607     }
608
609     String JavaDoc id = attributes.getValue("id");
610     String JavaDoc type = attributes.getValue("type");
611     Object JavaDoc value = attributes.getValue("value");
612     String JavaDoc visibleString = attributes.getValue("visible");
613
614     boolean visible = true;
615     if (visibleString != null) {
616     visibleString = visibleString.trim().toLowerCase();
617     if (visibleString.length() > 0)
618         visible = "true".equals(visibleString);
619     }
620
621     // If this is a dataSource column, make sure the column exists.
622
if ("column".equals(type) && findColumn(value.toString()) == null) {
623     field = null;
624     return;
625     }
626
627     // If we are converting formulas without id numbers, change our value
628
// (a pointer to the formula itself) from the formula's name to the
629
// formula's newly-created id.
630
if ("formula".equals(type) && formulasToConvert != null && value != null) {
631     Formula f = ((FormulaConversion)formulasToConvert.get(value)).formula;
632     if (f != null)
633         value = f.getId();
634     }
635
636     field =
637     Field.create(new Long JavaDoc(id), getReport(), section, type, value, visible);
638     if (field instanceof AggregateField && group != null)
639     ((AggregateField)field).setGroup(group);
640
641     section.addField(field);
642 }
643
644 /** Reads and sets the current field's bounds rectangle. */
645 protected void bounds(Attributes attributes) {
646     if (field != null)
647     field.getBounds()
648         .setBounds(Double.parseDouble(attributes.getValue("x")),
649                Double.parseDouble(attributes.getValue("y")),
650                Double.parseDouble(attributes.getValue("width")),
651                Double.parseDouble(attributes.getValue("height")));
652 }
653
654 /** * Reads and creates the current field's format. */
655 protected void format(Attributes attributes) {
656     if (field == null)
657     return;
658
659     Format format = field.getFormat();
660     String JavaDoc val;
661
662     if ((val = attributes.getValue("font")) != null)
663     format.setFontFamilyName(val);
664     if ((val = attributes.getValue("size")) != null)
665     format.setSize(Double.parseDouble(val));
666     if ((val = attributes.getValue("bold")) != null)
667     format.setBold("true".equals(val));
668     if ((val = attributes.getValue("italic")) != null)
669     format.setItalic("true".equals(val));
670     if ((val = attributes.getValue("underline")) != null)
671     format.setUnderline("true".equals(val));
672     if ((val = attributes.getValue("wrap")) != null)
673     format.setWrap("true".equals(val));
674     if ((val = attributes.getValue("align")) != null)
675     format.setAlign(Format.alignFromString(val));
676     if ((val = attributes.getValue("color")) != null)
677     format.setColor(parseColor(val));
678     if ((val = attributes.getValue("format")) != null)
679     format.setFormat(val);
680 }
681
682 /** Parses color string and returns a <code>java.awt.Color</code>. */
683 protected Color JavaDoc parseColor(String JavaDoc val) {
684     StringTokenizer tok = new StringTokenizer(val, ";");
685     int r = Integer.parseInt(tok.nextToken().trim());
686     int g = Integer.parseInt(tok.nextToken().trim());
687     int b = Integer.parseInt(tok.nextToken().trim());
688     int a = Integer.parseInt(tok.nextToken().trim());
689     return new Color JavaDoc(r, g, b, a);
690 }
691
692 /** Reads and creates a new field border. */
693 protected void border(Attributes attributes) {
694     if (field != null) {
695     border = new Border(field);
696     field.setBorder(border);
697
698     String JavaDoc val = attributes.getValue("color");
699     if (val != null)
700         border.setColor(parseColor(val));
701     }
702 }
703
704 /** Reads and creates a new border edge. */
705 protected void edge(Attributes attributes) {
706     if (field == null)
707     return;
708
709     String JavaDoc val = attributes.getValue("style");
710     int style = BorderEdge.styleFromString(val);
711
712     val = attributes.getValue("thickness");
713     double thickness = (val == null)
714     ? BorderEdge.DEFAULT_THICKNESS : Double.parseDouble(val);
715
716     val = attributes.getValue("number");
717     int num = (val == null)
718     ? BorderEdge.DEFAULT_NUMBER : Integer.parseInt(val);
719
720     BorderEdge edge = new BorderEdge(style, thickness, num);
721
722     String JavaDoc loc = attributes.getValue("location");
723     if ("top".equals(loc)) border.setTop(edge);
724     else if ("bottom".equals(loc)) border.setBottom(edge);
725     else if ("left".equals(loc)) border.setLeft(edge);
726     else if ("right".equals(loc)) border.setRight(edge);
727 }
728
729 /** Reads and creates a new line. */
730 protected void line(Attributes attributes) {
731     String JavaDoc val = attributes.getValue("thickness");
732     double thickness = (val == null) ? 1.0 : Double.parseDouble(val);
733     Color JavaDoc color = null;
734     if ((val = attributes.getValue("color")) != null)
735     color = parseColor(val);
736
737     val = attributes.getValue("visible");
738     boolean visible = true;
739     if (val != null) {
740     val = val.trim().toLowerCase();
741     if (val.length() > 0)
742         visible = "true".equals(val);
743     }
744
745     section.lines.add(line = new Line(getReport(), section, thickness, color,
746                       visible));
747 }
748
749 /** Reads a line's point and adds it to the current line. */
750 protected void point(Attributes attributes) {
751     line.addEndPoint(Double.parseDouble(attributes.getValue("x")),
752              Double.parseDouble(attributes.getValue("y")));
753 }
754
755 /** Reads paper size name and orientation. */
756 protected void paper(Attributes attributes) {
757     int orientation = PaperFormat.PORTRAIT; // Default value
758
String JavaDoc orientationStr = attributes.getValue("orientation");
759     if (orientationStr != null
760     && "landscape".equals(orientationStr.toLowerCase()))
761     orientation = PaperFormat.LANDSCAPE;
762
763     PaperFormat pf =
764     PaperFormat.get(orientation, attributes.getValue("name"));
765     if (pf != null)
766     getReport().setPaperFormat(pf);
767 }
768
769 /** Reads suppression proc. */
770 protected void suppressionProc(Attributes attributes) {
771     String JavaDoc state = attributes.getValue("hide");
772     if (state != null && state.length() > 0) {
773     SuppressionProc sp = section.getSuppressionProc();
774     state = state.trim().toLowerCase();
775     if ("true".equals(state)) sp.setHidden(true);
776     }
777 }
778
779 /**
780  * Returns the column identified by its name. The first time we can not find
781  * a column, we report an error to the user.
782  *
783  * @param fullName a column name
784  * @return a dataSource column
785  */

786 protected Column findColumn(String JavaDoc fullName) {
787     Column col = getReport().findColumn(fullName);
788     if (col == null && !missingColumnSeen) {
789     missingColumnSeen = true;
790     ErrorHandler.error(I18N.get("ReportReader.the_column")
791                + ' ' + fullName + ' '
792                + I18N.get("ReportReader.column_unknown"));
793     }
794     return col;
795 }
796
797 /**
798  * Returns the selectable identified by its id and type. The first time we can
799  * not find one, we report an error to the user.
800  *
801  * @param idStr an id string
802  * @param typeStr a type string ("column", "usercol")
803  * @return a dataSource column
804  */

805 protected Selectable findSelectable(String JavaDoc idStr, String JavaDoc typeStr) {
806     Selectable g = getReport().findSelectable(idStr, typeStr);
807     if (g == null && !missingColumnSeen) {
808     missingColumnSeen = true;
809     ErrorHandler.error(I18N.get("ReportReader.the_column")
810                + ' ' + idStr + " (" + typeStr + ") "
811                + I18N.get("ReportReader.column_unknown"));
812     }
813     return g;
814 }
815
816 }
817
Popular Tags