001: package com.xoetrope.io;
002:
003: import java.awt.Color;
004: import java.io.IOException;
005: import java.util.Enumeration;
006: import net.xoetrope.xui.XProjectManager;
007: import net.xoetrope.xui.style.XStyle;
008: import net.xoetrope.xui.style.XStyleManager;
009:
010: /**
011: * A utility class to help export HTML
012: *
013: * <p> Copyright (c) Xoetrope Ltd., 2001-2006, This software is licensed under
014: * the GNU Public License (GPL), please see license.txt for more details. If
015: * you make commercial use of this software you must purchase a commercial
016: * license from Xoetrope.</p>
017: * <p> $Revision: 1.10 $</p>
018: * @deprecated use the com.xoetrope.export classes instead
019: */
020: public class HtmlExportHelper extends XExportHelper {
021: /**
022: * A flag indicating that the exporter is in the process of exporting a table
023: */
024: protected boolean isInTable;
025:
026: /**
027: * A flag indicating that the exporter is in the process of exporting a table
028: * header
029: */
030: protected boolean isInTableHeader;
031:
032: /**
033: * A flag indicating that the exporter is in the process of exporting a table
034: * record
035: */
036: protected boolean isInRecord;
037:
038: /**
039: * The style manager
040: */
041: protected XStyleManager styleManager;
042:
043: /**
044: * Is this an alternative table row
045: */
046: private boolean altRecord = true;
047:
048: /**
049: * Setup the exporter for HTML. Prepare for a new document.
050: */
051: public HtmlExportHelper() {
052: setOutputElementNames(true);
053: setOutputFieldNames(true);
054: beginElement = "<p>";
055: endElement = "</p>";
056: leftDelimiter = rightDelimiter = "";
057: fieldSeparator = " ";
058: fieldNameSeparator = ": ";
059: elementClosure = " ";
060: defaultExtension = ".html";
061:
062: styleManager = XProjectManager.getStyleManager();
063: }
064:
065: /**
066: * Write the opening of a document
067: * @throws IOException thrown if the ooutput stream is not ready or in some other invalid state
068: */
069: public void startDocument() throws IOException {
070: writer.write("<html>");
071: writer.write(lineFeed);
072: writer.write("<head>");
073: writer.write(lineFeed);
074: writer.write("<title>CoolSelector Export</title>");
075: writer.write(lineFeed);
076: writeStyles();
077: writer
078: .write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">");
079: writer.write(lineFeed);
080: writer.write("</head>");
081: writer.write(lineFeed);
082: writer.write("<body bgcolor=\"#FFFFFF\">");
083: writer.write(lineFeed);
084: }
085:
086: /**
087: * Write the styles
088: */
089: public void writeStyles() throws IOException {
090: writer.write("<style type=\"text/css\">");
091: writer.write(lineFeed);
092:
093: Enumeration styleNames = styles.keys();
094: while (styleNames.hasMoreElements())
095: writeCssStyle((String) styleNames.nextElement());
096:
097: writer.write("</style>");
098: writer.write(lineFeed);
099: }
100:
101: /**
102: * Write the ending of a document
103: * @throws IOException thrown if the ooutput stream is not ready or in some other invalid state
104: */
105: public void endDocument() throws IOException {
106: writer.write("</html>");
107: writer.write(lineFeed);
108: }
109:
110: /**
111: * Write the opening of a table
112: * @throws IOException thrown if the ooutput stream is not ready or in some other invalid state
113: */
114: public void startTable() throws IOException {
115: writer
116: .write("<table width=\"95%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">");
117: writer.write(lineFeed);
118: isInTable = true;
119: }
120:
121: /**
122: * Write the ending of a table
123: * @throws IOException thrown if the ooutput stream is not ready or in some other invalid state
124: */
125: public void endTable() throws IOException {
126: writer.write("</table>");
127: writer.write(lineFeed);
128: isInTable = false;
129: isInTableHeader = false;
130: }
131:
132: /**
133: * Write the opening of a table record
134: * @throws IOException thrown if the ooutput stream is not ready or in some other invalid state
135: */
136: public void startRecord() throws IOException {
137: altRecord = !altRecord;
138: writer.write("<tr");
139: if (altRecord) {
140: writer.write(" bgcolor=\"");
141: writeCssColor("table", false);
142: writer.write("\"");
143: }
144:
145: writer.write(">");
146: writer.write(lineFeed);
147: isInRecord = true;
148: }
149:
150: /**
151: * Write the ending of a table record
152: * @throws IOException thrown if the ooutput stream is not ready or in some other invalid state
153: */
154: public void endRecord() throws IOException {
155: writer.write("</tr>");
156: writer.write(lineFeed);
157: isInRecord = true;
158: }
159:
160: /**
161: * Write the opening of a table record
162: * @throws IOException thrown if the ooutput stream is not ready or in some other invalid state
163: */
164: public void startHeader() throws IOException {
165: writer.write(lineFeed);
166: isInTableHeader = true;
167: startRecord();
168: }
169:
170: /**
171: * Write the ending of a table record
172: * @throws IOException thrown if the ooutput stream is not ready or in some other invalid state
173: */
174: public void endHeader() throws IOException {
175: writer.write(lineFeed);
176: endRecord();
177: writer.write(lineFeed);
178: isInTableHeader = false;
179: }
180:
181: /**
182: * Output a blank line
183: * @throws IOException thrown if the stream is not ready or if it is in an invalid state
184: */
185: public void writeBlankLine() throws IOException {
186: writer.write("<p>");
187: writer.write("</p>");
188:
189: writer.write("<p>");
190: writer.write("</p>");
191:
192: writer.write(lineFeed);
193: }
194:
195: /**
196: * Output a line break
197: * @throws IOException thrown if the stream is not ready or if it is in an invalid state
198: */
199: public void writeBreak() throws IOException {
200: writer.write("<br>");
201: writer.write(lineFeed);
202: }
203:
204: /**
205: * Write a field
206: * @param name the field name
207: * @param value the field value
208: * @throws IOException thrown if the ooutput stream is not ready or in some other invalid state
209: */
210: public void writeField(String name, String value)
211: throws IOException {
212: if (!isInTable) {
213: if (!firstField)
214: writer.write(fieldSeparator);
215: else
216: firstField = false;
217:
218: writer.write("<b>");
219: writer.write(prepareFieldName(name));
220: writeStyleClosure();
221: writer.write("</b>");
222:
223: writer.write(leftDelimiter);
224: if (value != null)
225: writer.write(value);
226: writer.write(rightDelimiter);
227: } else {
228: String alignment = (String) hints.get("Alignment");
229: if (!isInTableHeader) {
230: writer.write("<td>");
231:
232: if (alignment != null) {
233: if (alignment.equalsIgnoreCase("Right"))
234: writer.write("<div align=\"right\">");
235: }
236:
237: if (value != null) {
238: writeStyle(altRecord ? "alttable" : "table");
239: writer.write(value);
240: writeStyleClosure();
241: }
242: if (alignment != null) {
243: if (alignment.equalsIgnoreCase("Right"))
244: writer.write("</div>");
245: }
246: writer.write("</td>");
247: } else {
248: writer.write("<th>");
249: if (value != null) {
250: writeStyle("tableHeader");
251: if (alignment != null) {
252: if (alignment.equalsIgnoreCase("Right"))
253: writer.write("<div align=\"right\">");
254: }
255:
256: writer.write(name);
257:
258: if (alignment != null) {
259: if (alignment.equalsIgnoreCase("Right"))
260: writer.write("</div>");
261: }
262: }
263: writeStyleClosure();
264: writer.write("</th>");
265:
266: }
267: }
268: }
269:
270: /**
271: * Write the section title and terminate with a line feed, new line as appropriate
272: * @param text the text to output
273: * @throws IOException thrown if the ooutput stream is not ready or in some other invalid state
274: */
275: public void writeSectionTitle(String text) throws IOException {
276: writer.write("<h2>");
277: startElement(text);
278: endElement();
279: writer.write("</h2>");
280: }
281:
282: /**
283: * Write the section title and terminate with a line feed, new line as appropriate
284: * @param text the text to output
285: * @param styleName the style of the section title or the section name e.g. HEADER_STYLE
286: * @throws IOException thrown if the stream is not ready or if it is in an invalid state
287: */
288: public void writeSectionTitle(String text, String styleName)
289: throws IOException {
290: boolean rc = writeStyle(styleName);
291: if (!rc)
292: writer.write("<h2>");
293: else
294: writer.write(beginElement);
295: writer.write(text);
296: if (!rc)
297: writer.write("</h2>");
298: else
299: writer.write(endElement);
300: writeStyleClosure();
301: }
302:
303: /**
304: * Write a style description
305: * @param the style of the section title or the section name e.g. HEADER_STYLE
306: */
307: private boolean writeCssStyle(String styleName) throws IOException {
308: String stylePath = (String) styles.get(styleName);
309: if (stylePath == null)
310: stylePath = "base";
311: XStyle style = styleManager.getStyle(stylePath);
312: if (style != null) {
313: String styleString = " ." + styleName + " {";
314: if (style.getStyleAsInt(XStyle.FONT_WEIGHT) > 0)
315: styleString += " font-weight: bold;";
316: if (style.getStyleAsInt(XStyle.FONT_ITALIC) > 0)
317: styleString += " font-style: italic;";
318: Color fontColor = style.getStyleAsColor(XStyle.COLOR_FORE);
319: Color fontBkColor = style
320: .getStyleAsColor(XStyle.COLOR_BACK);
321: styleString += " font-family:\""
322: + style.getStyleAsString(XStyle.FONT_FACE) + "\";"
323: + " font-size:"
324: + style.getStyleAsString(XStyle.FONT_SIZE) + ";"
325: + " color:#" + toHexString(fontColor.getRed())
326: + toHexString(fontColor.getGreen())
327: + toHexString(fontColor.getBlue()) + ";"
328: + " background:#"
329: + toHexString(fontBkColor.getRed())
330: + toHexString(fontBkColor.getGreen())
331: + toHexString(fontBkColor.getBlue()) + ";" + "}";
332: writer.write(styleString);
333: writer.write(lineFeed);
334: return true;
335: }
336: return false;
337: }
338:
339: /**
340: * Write a style color
341: * @param the style of the section title or the section name e.g. HEADER_STYLE
342: */
343: private void writeCssColor(String styleName, boolean frgd)
344: throws IOException {
345: String stylePath = (String) styles.get(styleName);
346: if (stylePath == null)
347: stylePath = "base";
348: XStyle style = styleManager.getStyle(stylePath);
349: if (style != null) {
350: Color color = style
351: .getStyleAsColor(frgd ? XStyle.COLOR_FORE
352: : XStyle.COLOR_BACK);
353: writer.write("#" + toHexString(color.getRed())
354: + toHexString(color.getGreen())
355: + toHexString(color.getBlue()));
356: }
357: }
358:
359: /**
360: * Write a field
361: * @param name the field name
362: * @param value the field value
363: * @param styleName the style to apply
364: * @throws IOException thrown if the stream is not ready or if it is in an invalid state
365: */
366: public void writeText(String name, String value, String styleName)
367: throws IOException {
368: writeStyle(styleName);
369: if (!firstField)
370: writer.write(fieldSeparator);
371: else
372: firstField = false;
373: if (outputFieldNames) {
374: writer.write(name);
375: writer.write(fieldNameSeparator);
376: }
377: writer.write(leftDelimiter);
378: if (value != null)
379: writer.write(value);
380: writer.write(rightDelimiter);
381: writeStyleClosure();
382: }
383:
384: /**
385: * Output an image
386: * @param imageName the file name
387: * @param altText the alternative text
388: */
389: public void writeImage(String imageName, String altText)
390: throws IOException {
391: String alignment = (String) hints.get("Alignment");
392: if (alignment != null) {
393: if (alignment.equalsIgnoreCase("Right"))
394: writer.write("<div position: relative; right: 1cm;>");
395: }
396: writer.write("<img src=\"" + imageName + "\" alt=\"" + altText
397: + "\"/>");
398: if (alignment != null) {
399: if (alignment.equalsIgnoreCase("Right"))
400: writer.write("</div>");
401: }
402: }
403:
404: /**
405: * Write a style description
406: * @param the style of the section title or the section name e.g. HEADER_STYLE
407: */
408: private boolean writeStyle(String styleName) throws IOException {
409: writer.write("<span class=\"" + styleName + "\">");
410: writer.write(lineFeed);
411: return true;
412: }
413:
414: /**
415: * Close a style description
416: */
417: private boolean writeStyleClosure() throws IOException {
418: writer.write("</span>");
419: writer.write(lineFeed);
420: return false;
421: }
422:
423: /**
424: * Write the begining/opening of an element
425: * @param elementName the element name
426: * @throws IOException thrown if the ooutput stream is not ready or in some other invalid state
427: */
428: public void startElement(String elementName) throws IOException {
429: if (!isInTable) {
430: writer.write(beginElement);
431: writer.write(elementName);
432: writer.write(fieldSeparator);
433: }
434: elementNames.push(lastElementName = elementName);
435: firstField = true;
436: }
437:
438: /**
439: * Write the begining/opening of an element
440: * @param elementName the element name
441: * @param styleName the style of the section title or the section name e.g. HEADER_STYLE
442: * @throws IOException thrown if the ooutput stream is not ready or in some other invalid state
443: */
444: public void startElement(String elementName, String styleName)
445: throws IOException {
446: if (!isInTable) {
447: writer.write(beginElement);
448: writer.write(elementName);
449: writeStyle(styleName);
450: writer.write(fieldSeparator);
451: }
452: elementNames.push(lastElementName = elementName);
453: firstField = true;
454: }
455:
456: /**
457: * Write the matching ending element
458: * @throws IOException thrown if the ooutput stream is not ready or in some other invalid state
459: */
460: public void matchElement() throws IOException {
461: if (elementNames.size() > 0) {
462: if (!isInTable) {
463: String startElementName = elementNames.pop().toString();
464: writer.write(beginElement);
465: writer.write(elementClosure);
466: writer.write(startElementName);
467: writer.write(endElement);
468: writer.write(lineFeed);
469: }
470: }
471: }
472:
473: /**
474: * Write the end of an element opening
475: * @throws IOException thrown if the ooutput stream is not ready or in some other invalid state
476: */
477: public void endElement() throws IOException {
478: if (!isInTable) {
479: writer.write(endElement);
480: writer.write(lineFeed);
481: }
482: }
483:
484: /**
485: * Write the end of an element opening
486: * @param styleName the style of the section title or the section name e.g. HEADER_STYLE
487: * @throws IOException thrown if the ooutput stream is not ready or in some other invalid state
488: */
489: public void endElement(String styleName) throws IOException {
490: if (!isInTable) {
491: writeStyleClosure();
492: writer.write(endElement);
493: writer.write(lineFeed);
494: }
495: }
496:
497: /**
498: * Write the closing of an element
499: * @throws IOException thrown if the ooutput stream is not ready or in some other invalid state
500: */
501: public void closeElement() throws IOException {
502: elementNames.pop().toString(); // Discard the last element
503: if (!isInTable) {
504: writer.write(elementClosure);
505: writer.write(endElement);
506: }
507:
508: writer.write(lineFeed);
509: }
510:
511: /**
512: * Write the end of a section
513: * @throws IOException thrown if the ooutput stream is not ready or in some other invalid state
514: */
515: public void writeSectionEnd() throws IOException {
516: matchElement();
517: }
518:
519: /**
520: * Output a line/ruler
521: * @throws IOException thrown if the stream is not ready or if it is in an invalid state
522: */
523: public void writeHorizontalLine() throws IOException {
524: writer.write("<hr>");
525: }
526:
527: /**
528: * Flushes and closes any existing stream
529: * @throws java.io.IOException thrown if the ooutput stream is not ready or in some other invalid state
530: */
531: public void close() throws IOException {
532: if (writer != null) {
533: while (!elementNames.isEmpty())
534: matchElement();
535:
536: writer.flush();
537: writer.close();
538: }
539: }
540:
541: /**
542: * Prepare the field name for export
543: * @param name the raw name
544: * @return the prepared value
545: */
546: protected String prepareFieldName(String name) {
547: String targets = ":. ;&";
548: for (int i = 0; i < targets.length(); i++) {
549: char target = targets.charAt(i);
550: if (name.indexOf(target) > 0)
551: name = name.replace(target, '_');
552: }
553: return name;
554: }
555:
556: /**
557: * Get a two letter hex string for the decimal value in the range 0-255
558: * @param value the int value in the range 0-255
559: * @return the two letter hex value
560: */
561: public static String toHexString(int value) {
562: String hex = Integer.toHexString(value).toUpperCase();
563: if (hex.length() < 2)
564: return "0" + hex;
565:
566: return hex;
567: }
568: }
|