Source Code Cross Referenced for Table.java in  » J2EE » enhydra » com » nwalsh » xalan » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » J2EE » enhydra » com.nwalsh.xalan 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        // Verbatim.java - Xalan extensions supporting DocBook verbatim environments
002:
003:        package com.nwalsh.xalan;
004:
005:        import java.util.Hashtable;
006:        import org.xml.sax.*;
007:        import org.xml.sax.helpers.AttributesImpl;
008:        import org.w3c.dom.*;
009:        import org.w3c.dom.traversal.NodeIterator;
010:
011:        import javax.xml.transform.TransformerException;
012:
013:        import org.apache.xpath.objects.XObject;
014:        import org.apache.xpath.XPathContext;
015:        import org.apache.xalan.extensions.ExpressionContext;
016:        import org.apache.xml.utils.DOMBuilder;
017:        import javax.xml.parsers.DocumentBuilder;
018:        import javax.xml.parsers.DocumentBuilderFactory;
019:        import javax.xml.parsers.ParserConfigurationException;
020:        import org.apache.xml.utils.QName;
021:        import org.apache.xpath.DOMHelper;
022:        import org.apache.xml.utils.AttList;
023:
024:        /**
025:         * <p>Xalan extensions supporting Tables</p>
026:         *
027:         * <p>$Id: Table.java,v 1.4 2005-08-30 08:14:58 draganr Exp $</p>
028:         *
029:         * <p>Copyright (C) 2000 Norman Walsh.</p>
030:         *
031:         * <p>This class provides a
032:         * <a href="http://xml.apache.org/xalan/">Xalan</a>
033:         * implementation of some code to adjust CALS Tables to HTML
034:         * Tables.</p>
035:         *
036:         * <p><b>Column Widths</b></p>
037:         * <p>The <tt>adjustColumnWidths</tt> method takes a result tree
038:         * fragment (assumed to contain the colgroup of an HTML Table)
039:         * and returns the result tree fragment with the column widths
040:         * adjusted to HTML terms.</p>
041:         *
042:         * <p><b>Convert Lengths</b></p>
043:         * <p>The <tt>convertLength</tt> method takes a length specification
044:         * of the form 9999.99xx (where "xx" is a unit) and returns that length
045:         * as an integral number of pixels. For convenience, percentage lengths
046:         * are returned unchanged.</p>
047:         * <p>The recognized units are: inches (in), centimeters (cm),
048:         * millimeters (mm), picas (pc, 1pc=12pt), points (pt), and pixels (px).
049:         * A number with no units is assumed to be pixels.</p>
050:         *
051:         * <p><b>Change Log:</b></p>
052:         * <dl>
053:         * <dt>1.0</dt>
054:         * <dd><p>Initial release.</p></dd>
055:         * </dl>
056:         *
057:         * @author Norman Walsh
058:         * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
059:         *
060:         * @version $Id: Table.java,v 1.4 2005-08-30 08:14:58 draganr Exp $
061:         *
062:         */
063:        public class Table {
064:            /** The number of pixels per inch */
065:            private static int pixelsPerInch = 96;
066:
067:            /** The hash used to associate units with a length in pixels. */
068:            protected static Hashtable unitHash = null;
069:
070:            /** The FO namespace name. */
071:            protected static String foURI = "http://www.w3.org/1999/XSL/Format";
072:
073:            /**
074:             * <p>Constructor for Verbatim</p>
075:             *
076:             * <p>All of the methods are static, so the constructor does nothing.</p>
077:             */
078:            public Table() {
079:            }
080:
081:            /** Initialize the internal hash table with proper values. */
082:            protected static void initializeHash() {
083:                unitHash = new Hashtable();
084:                unitHash.put("in", new Float(pixelsPerInch));
085:                unitHash.put("cm", new Float(pixelsPerInch / 2.54));
086:                unitHash.put("mm", new Float(pixelsPerInch / 25.4));
087:                unitHash.put("pc", new Float((pixelsPerInch / 72) * 12));
088:                unitHash.put("pt", new Float(pixelsPerInch / 72));
089:                unitHash.put("px", new Float(1));
090:            }
091:
092:            /** Set the pixels-per-inch value. Only positive values are legal. */
093:            public static void setPixelsPerInch(int value) {
094:                if (value > 0) {
095:                    pixelsPerInch = value;
096:                    initializeHash();
097:                }
098:            }
099:
100:            /** Return the current pixels-per-inch value. */
101:            public int getPixelsPerInch() {
102:                return pixelsPerInch;
103:            }
104:
105:            /**
106:             * <p>Convert a length specification to a number of pixels.</p>
107:             *
108:             * <p>The specified length should be of the form [+/-]999.99xx,
109:             * where xx is a valid unit.</p>
110:             */
111:            public static int convertLength(String length) {
112:                // The format of length should be 999.999xx
113:                int sign = 1;
114:                String digits = "";
115:                String units = "";
116:                char lench[] = length.toCharArray();
117:                float flength = 0;
118:                boolean done = false;
119:                int pos = 0;
120:                float factor = 1;
121:                int pixels = 0;
122:
123:                if (unitHash == null) {
124:                    initializeHash();
125:                }
126:
127:                if (lench[pos] == '+' || lench[pos] == '-') {
128:                    if (lench[pos] == '-') {
129:                        sign = -1;
130:                    }
131:                    pos++;
132:                }
133:
134:                while (!done) {
135:                    if (pos >= lench.length) {
136:                        done = true;
137:                    } else {
138:                        if ((lench[pos] > '9' || lench[pos] < '0')
139:                                && lench[pos] != '.') {
140:                            done = true;
141:                            units = length.substring(pos);
142:                        } else {
143:                            digits += lench[pos++];
144:                        }
145:                    }
146:                }
147:
148:                try {
149:                    flength = Float.parseFloat(digits);
150:                } catch (NumberFormatException e) {
151:                    System.out.println(digits
152:                            + " is not a number; 1 used instead.");
153:                    flength = 1;
154:                }
155:
156:                Float f = null;
157:
158:                if (!units.equals("")) {
159:                    f = (Float) unitHash.get(units);
160:                    if (f == null) {
161:                        System.out.println(units
162:                                + " is not a known unit; 1 used instead.");
163:                        factor = 1;
164:                    } else {
165:                        factor = f.floatValue();
166:                    }
167:                } else {
168:                    factor = 1;
169:                }
170:
171:                f = new Float(flength * factor);
172:
173:                pixels = f.intValue() * sign;
174:
175:                return pixels;
176:            }
177:
178:            /**
179:             * <p>Adjust column widths in an HTML table.</p>
180:             *
181:             * <p>The specification of column widths in CALS (a relative width
182:             * plus an optional absolute width) are incompatible with HTML column
183:             * widths. This method adjusts CALS column width specifiers in an
184:             * attempt to produce equivalent HTML specifiers.</p>
185:             *
186:             * <p>In order for this method to work, the CALS width specifications
187:             * should be placed in the "width" attribute of the &lt;col>s within
188:             * a &lt;colgroup>. Then the colgroup result tree fragment is passed
189:             * to this method.</p>
190:             *
191:             * <p>This method makes use of two parameters from the XSL stylesheet
192:             * that calls it: <code>nominal.table.width</code> and
193:             * <code>table.width</code>. The value of <code>nominal.table.width</code>
194:             * must be an absolute distance. The value of <code>table.width</code>
195:             * can be either absolute or relative.</p>
196:             *
197:             * <p>Presented with a mixture of relative and
198:             * absolute lengths, the table width is used to calculate
199:             * appropriate values. If the <code>table.width</code> is relative,
200:             * the nominal width is used for this calculation.</p>
201:             *
202:             * <p>There are three possible combinations of values:</p>
203:             *
204:             * <ol>
205:             * <li>There are no relative widths; in this case the absolute widths
206:             * are used in the HTML table.</li>
207:             * <li>There are no absolute widths; in this case the relative widths
208:             * are used in the HTML table.</li>
209:             * <li>There are a mixture of absolute and relative widths:
210:             *   <ol>
211:             *     <li>If the table width is absolute, all widths become absolute.</li>
212:             *     <li>If the table width is relative, make all the widths absolute
213:             *         relative to the nominal table width then turn them all
214:             *         back into relative widths.</li>
215:             *   </ol>
216:             * </li>
217:             * </ol>
218:             *
219:             * @param context The stylesheet context; supplied automatically by Xalan
220:             * @param rtf The result tree fragment containing the colgroup.
221:             *
222:             * @return The result tree fragment containing the adjusted colgroup.
223:             *
224:             */
225:
226:            public DocumentFragment adjustColumnWidths(
227:                    ExpressionContext context, NodeIterator xalanNI) {
228:
229:                int nominalWidth = convertLength(Params.getString(context,
230:                        "nominal.table.width"));
231:                String tableWidth = Params.getString(context, "table.width");
232:                String styleType = Params.getString(context,
233:                        "stylesheet.result.type");
234:                boolean foStylesheet = styleType.equals("fo");
235:
236:                DocumentFragment xalanRTF = (DocumentFragment) xalanNI
237:                        .nextNode();
238:                Element colgroup = (Element) xalanRTF.getFirstChild();
239:
240:                // N.B. ...stree.ElementImpl doesn't implement getElementsByTagName()
241:
242:                Node firstCol = null;
243:                // If this is an FO tree, there might be no colgroup...
244:                if (colgroup.getLocalName().equals("colgroup")) {
245:                    firstCol = colgroup.getFirstChild();
246:                } else {
247:                    firstCol = colgroup;
248:                }
249:
250:                // Count the number of columns...
251:                Node child = firstCol;
252:                int numColumns = 0;
253:                while (child != null) {
254:                    if (child.getNodeType() == Node.ELEMENT_NODE
255:                            && (child.getNodeName().equals("col") || (child
256:                                    .getNamespaceURI().equals(foURI) && child
257:                                    .getLocalName().equals("table-column")))) {
258:                        numColumns++;
259:                    }
260:
261:                    child = child.getNextSibling();
262:                }
263:
264:                String widths[] = new String[numColumns];
265:                Element columns[] = new Element[numColumns];
266:                int colnum = 0;
267:
268:                child = firstCol;
269:                while (child != null) {
270:                    if (child.getNodeType() == Node.ELEMENT_NODE
271:                            && (child.getNodeName().equals("col") || (child
272:                                    .getNamespaceURI().equals(foURI) && child
273:                                    .getLocalName().equals("table-column")))) {
274:                        Element col = (Element) child;
275:
276:                        columns[colnum] = col;
277:
278:                        if (foStylesheet) {
279:                            if (col.getAttribute("column-width") == null) {
280:                                widths[colnum] = "1*";
281:                            } else {
282:                                widths[colnum] = col
283:                                        .getAttribute("column-width");
284:                            }
285:                        } else {
286:                            if (col.getAttribute("width") == null) {
287:                                widths[colnum] = "1*";
288:                            } else {
289:                                widths[colnum] = col.getAttribute("width");
290:                            }
291:                        }
292:
293:                        colnum++;
294:                    }
295:                    child = child.getNextSibling();
296:                }
297:
298:                float relTotal = 0;
299:                float relParts[] = new float[numColumns];
300:
301:                float absTotal = 0;
302:                float absParts[] = new float[numColumns];
303:
304:                for (int count = 0; count < numColumns; count++) {
305:                    String width = widths[count];
306:                    int pos = width.indexOf("*");
307:                    if (pos >= 0) {
308:                        String relPart = width.substring(0, pos);
309:                        String absPart = width.substring(pos + 1);
310:
311:                        try {
312:                            float rel = Float.parseFloat(relPart);
313:                            relTotal += rel;
314:                            relParts[count] = rel;
315:                        } catch (NumberFormatException e) {
316:                            System.out.println(relPart
317:                                    + " is not a valid relative unit.");
318:                        }
319:
320:                        int pixels = 0;
321:                        if (absPart != null && !absPart.equals("")) {
322:                            pixels = convertLength(absPart);
323:                        }
324:
325:                        absTotal += pixels;
326:                        absParts[count] = pixels;
327:                    } else {
328:                        relParts[count] = 0;
329:
330:                        int pixels = 0;
331:                        if (width != null && !width.equals("")) {
332:                            pixels = convertLength(width);
333:                        }
334:
335:                        absTotal += pixels;
336:                        absParts[count] = pixels;
337:                    }
338:                }
339:
340:                // Ok, now we have the relative widths and absolute widths in
341:                // two parallel arrays.
342:                //
343:                // - If there are no relative widths, output the absolute widths
344:                // - If there are no absolute widths, output the relative widths
345:                // - If there are a mixture of relative and absolute widths,
346:                //   - If the table width is absolute, turn these all into absolute
347:                //     widths.
348:                //   - If the table width is relative, turn these all into absolute
349:                //     widths in the nominalWidth and then turn them back into
350:                //     percentages.
351:
352:                if (relTotal == 0) {
353:                    for (int count = 0; count < numColumns; count++) {
354:                        Float f = new Float(absParts[count]);
355:                        if (foStylesheet) {
356:                            int pixels = f.intValue();
357:                            float inches = (float) pixels / pixelsPerInch;
358:                            widths[count] = inches + "in";
359:                        } else {
360:                            widths[count] = Integer.toString(f.intValue());
361:                        }
362:                    }
363:                } else if (absTotal == 0) {
364:                    for (int count = 0; count < numColumns; count++) {
365:                        float rel = relParts[count] / relTotal * 100;
366:                        Float f = new Float(rel);
367:                        widths[count] = Integer.toString(f.intValue());
368:                    }
369:                    widths = correctRoundingError(widths);
370:                } else {
371:                    int pixelWidth = nominalWidth;
372:
373:                    if (tableWidth.indexOf("%") <= 0) {
374:                        pixelWidth = convertLength(tableWidth);
375:                    }
376:
377:                    if (pixelWidth <= absTotal) {
378:                        System.out.println("Table is wider than table width.");
379:                    } else {
380:                        pixelWidth -= absTotal;
381:                    }
382:
383:                    absTotal = 0;
384:                    for (int count = 0; count < numColumns; count++) {
385:                        float rel = relParts[count] / relTotal * pixelWidth;
386:                        relParts[count] = rel + absParts[count];
387:                        absTotal += rel + absParts[count];
388:                    }
389:
390:                    if (tableWidth.indexOf("%") <= 0) {
391:                        for (int count = 0; count < numColumns; count++) {
392:                            Float f = new Float(relParts[count]);
393:                            if (foStylesheet) {
394:                                int pixels = f.intValue();
395:                                float inches = (float) pixels / pixelsPerInch;
396:                                widths[count] = inches + "in";
397:                            } else {
398:                                widths[count] = Integer.toString(f.intValue());
399:                            }
400:                        }
401:                    } else {
402:                        for (int count = 0; count < numColumns; count++) {
403:                            float rel = relParts[count] / absTotal * 100;
404:                            Float f = new Float(rel);
405:                            widths[count] = Integer.toString(f.intValue());
406:                        }
407:                        widths = correctRoundingError(widths);
408:                    }
409:                }
410:
411:                // Now rebuild the colgroup with the right widths
412:
413:                DocumentBuilderFactory docFactory = DocumentBuilderFactory
414:                        .newInstance();
415:                DocumentBuilder docBuilder = null;
416:
417:                try {
418:                    docBuilder = docFactory.newDocumentBuilder();
419:                } catch (ParserConfigurationException e) {
420:                    System.out.println("PCE!");
421:                    return xalanRTF;
422:                }
423:                Document doc = docBuilder.newDocument();
424:                DocumentFragment df = doc.createDocumentFragment();
425:                DOMBuilder rtf = new DOMBuilder(doc, df);
426:
427:                try {
428:                    String ns = colgroup.getNamespaceURI();
429:                    String localName = colgroup.getLocalName();
430:                    String name = colgroup.getTagName();
431:
432:                    if (colgroup.getLocalName().equals("colgroup")) {
433:                        rtf.startElement(ns, localName, name,
434:                                copyAttributes(colgroup));
435:                    }
436:
437:                    for (colnum = 0; colnum < numColumns; colnum++) {
438:                        Element col = columns[colnum];
439:
440:                        NamedNodeMap domAttr = col.getAttributes();
441:
442:                        AttributesImpl attr = new AttributesImpl();
443:                        for (int acount = 0; acount < domAttr.getLength(); acount++) {
444:                            Node a = domAttr.item(acount);
445:                            String a_ns = a.getNamespaceURI();
446:                            String a_localName = a.getLocalName();
447:
448:                            if ((foStylesheet && !a_localName
449:                                    .equals("column-width"))
450:                                    || !a_localName.equalsIgnoreCase("width")) {
451:                                attr.addAttribute(a.getNamespaceURI(), a
452:                                        .getLocalName(), a.getNodeName(),
453:                                        "CDATA", a.getNodeValue());
454:                            }
455:                        }
456:
457:                        if (foStylesheet) {
458:                            attr.addAttribute("", "column-width",
459:                                    "column-width", "CDATA", widths[colnum]);
460:                        } else {
461:                            attr.addAttribute("", "width", "width", "CDATA",
462:                                    widths[colnum]);
463:                        }
464:
465:                        rtf.startElement(col.getNamespaceURI(), col
466:                                .getLocalName(), col.getTagName(), attr);
467:                        rtf.endElement(col.getNamespaceURI(), col
468:                                .getLocalName(), col.getTagName());
469:                    }
470:
471:                    if (colgroup.getLocalName().equals("colgroup")) {
472:                        rtf.endElement(ns, localName, name);
473:                    }
474:                } catch (SAXException se) {
475:                    System.out.println("SE!");
476:                    return xalanRTF;
477:                }
478:
479:                return df;
480:            }
481:
482:            private Attributes copyAttributes(Element node) {
483:                AttributesImpl attrs = new AttributesImpl();
484:                NamedNodeMap nnm = node.getAttributes();
485:                for (int count = 0; count < nnm.getLength(); count++) {
486:                    Attr attr = (Attr) nnm.item(count);
487:                    String name = attr.getName();
488:                    if (name.startsWith("xmlns:") || name.equals("xmlns")) {
489:                        // Skip it; (don't ya just love it!!)
490:                    } else {
491:                        attrs.addAttribute(attr.getNamespaceURI(), attr
492:                                .getName(), attr.getName(), "CDATA", attr
493:                                .getValue());
494:                    }
495:                }
496:                return attrs;
497:            }
498:
499:            /**
500:             * Correct rounding errors introduced in calculating the width of each
501:             * column. Make sure they sum to 100% in the end.
502:             */
503:            protected String[] correctRoundingError(String widths[]) {
504:                int totalWidth = 0;
505:
506:                for (int count = 0; count < widths.length; count++) {
507:                    try {
508:                        int width = Integer.parseInt(widths[count]);
509:                        totalWidth += width;
510:                    } catch (NumberFormatException nfe) {
511:                        // nop; "can't happen"
512:                    }
513:                }
514:
515:                float totalError = 100 - totalWidth;
516:                float columnError = totalError / widths.length;
517:                float error = 0;
518:
519:                for (int count = 0; count < widths.length; count++) {
520:                    try {
521:                        int width = Integer.parseInt(widths[count]);
522:                        error = error + columnError;
523:                        if (error >= 1.0) {
524:                            int adj = (int) Math.round(Math.floor(error));
525:                            error = error - (float) Math.floor(error);
526:                            width = width + adj;
527:                            widths[count] = Integer.toString(width) + "%";
528:                        } else {
529:                            widths[count] = Integer.toString(width) + "%";
530:                        }
531:                    } catch (NumberFormatException nfe) {
532:                        // nop; "can't happen"
533:                    }
534:                }
535:
536:                return widths;
537:            }
538:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.