Source Code Cross Referenced for Table.java in  » J2EE » enhydra » com » nwalsh » saxon » 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.saxon 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        // Verbatim.java - Saxon extensions supporting DocBook verbatim environments
002:
003:        package com.nwalsh.saxon;
004:
005:        import java.util.Hashtable;
006:        import org.xml.sax.*;
007:        import org.w3c.dom.*;
008:        import javax.xml.transform.TransformerException;
009:        import com.icl.saxon.Controller;
010:        import com.icl.saxon.expr.*;
011:        import com.icl.saxon.om.*;
012:        import com.icl.saxon.pattern.*;
013:        import com.icl.saxon.Context;
014:        import com.icl.saxon.tree.*;
015:        import com.icl.saxon.functions.Extensions;
016:
017:        /**
018:         * <p>Saxon extensions supporting Tables</p>
019:         *
020:         * <p>$Id: Table.java,v 1.4 2005-08-30 08:14:58 draganr Exp $</p>
021:         *
022:         * <p>Copyright (C) 2000 Norman Walsh.</p>
023:         *
024:         * <p>This class provides a
025:         * <a href="http://users.iclway.co.uk/mhkay/saxon/">Saxon</a>
026:         * implementation of some code to adjust CALS Tables to HTML
027:         * Tables.</p>
028:         *
029:         * <p><b>Column Widths</b></p>
030:         * <p>The <tt>adjustColumnWidths</tt> method takes a result tree
031:         * fragment (assumed to contain the colgroup of an HTML Table)
032:         * and returns the result tree fragment with the column widths
033:         * adjusted to HTML terms.</p>
034:         *
035:         * <p><b>Convert Lengths</b></p>
036:         * <p>The <tt>convertLength</tt> method takes a length specification
037:         * of the form 9999.99xx (where "xx" is a unit) and returns that length
038:         * as an integral number of pixels. For convenience, percentage lengths
039:         * are returned unchanged.</p>
040:         * <p>The recognized units are: inches (in), centimeters (cm),
041:         * millimeters (mm), picas (pc, 1pc=12pt), points (pt), and pixels (px).
042:         * A number with no units is assumed to be pixels.</p>
043:         *
044:         * <p><b>Change Log:</b></p>
045:         * <dl>
046:         * <dt>1.0</dt>
047:         * <dd><p>Initial release.</p></dd>
048:         * </dl>
049:         *
050:         * @author Norman Walsh
051:         * <a href="mailto:ndw@nwalsh.com">ndw@nwalsh.com</a>
052:         *
053:         * @version $Id: Table.java,v 1.4 2005-08-30 08:14:58 draganr Exp $
054:         *
055:         */
056:        public class Table {
057:            /** The number of pixels per inch */
058:            private static int pixelsPerInch = 96;
059:
060:            /** The nominal table width (6in by default). */
061:            private static int nominalWidth = 6 * pixelsPerInch;
062:
063:            /** The default table width (100% by default). */
064:            private static String tableWidth = "100%";
065:
066:            /** Is this an FO stylesheet? */
067:            private static boolean foStylesheet = false;
068:
069:            /** The hash used to associate units with a length in pixels. */
070:            protected static Hashtable unitHash = null;
071:
072:            /**
073:             * <p>Constructor for Verbatim</p>
074:             *
075:             * <p>All of the methods are static, so the constructor does nothing.</p>
076:             */
077:            public Table() {
078:            }
079:
080:            /** Initialize the internal hash table with proper values. */
081:            protected static void initializeHash() {
082:                unitHash = new Hashtable();
083:                unitHash.put("in", new Float(pixelsPerInch));
084:                unitHash.put("cm", new Float(pixelsPerInch / 2.54));
085:                unitHash.put("mm", new Float(pixelsPerInch / 25.4));
086:                unitHash.put("pc", new Float((pixelsPerInch / 72) * 12));
087:                unitHash.put("pt", new Float(pixelsPerInch / 72));
088:                unitHash.put("px", new Float(1));
089:            }
090:
091:            /** Set the pixels-per-inch value. Only positive values are legal. */
092:            public static void setPixelsPerInch(int value) {
093:                if (value > 0) {
094:                    pixelsPerInch = value;
095:                    initializeHash();
096:                }
097:            }
098:
099:            /** Return the current pixels-per-inch value. */
100:            public int getPixelsPerInch() {
101:                return pixelsPerInch;
102:            }
103:
104:            /**
105:             * <p>Convert a length specification to a number of pixels.</p>
106:             *
107:             * <p>The specified length should be of the form [+/-]999.99xx,
108:             * where xx is a valid unit.</p>
109:             */
110:            public static int convertLength(String length) {
111:                // The format of length should be 999.999xx
112:                int sign = 1;
113:                String digits = "";
114:                String units = "";
115:                char lench[] = length.toCharArray();
116:                float flength = 0;
117:                boolean done = false;
118:                int pos = 0;
119:                float factor = 1;
120:                int pixels = 0;
121:
122:                if (unitHash == null) {
123:                    initializeHash();
124:                }
125:
126:                if (lench[pos] == '+' || lench[pos] == '-') {
127:                    if (lench[pos] == '-') {
128:                        sign = -1;
129:                    }
130:                    pos++;
131:                }
132:
133:                while (!done) {
134:                    if (pos >= lench.length) {
135:                        done = true;
136:                    } else {
137:                        if ((lench[pos] > '9' || lench[pos] < '0')
138:                                && lench[pos] != '.') {
139:                            done = true;
140:                            units = length.substring(pos);
141:                        } else {
142:                            digits += lench[pos++];
143:                        }
144:                    }
145:                }
146:
147:                try {
148:                    flength = Float.parseFloat(digits);
149:                } catch (NumberFormatException e) {
150:                    System.out.println(digits
151:                            + " is not a number; 1 used instead.");
152:                    flength = 1;
153:                }
154:
155:                Float f = null;
156:
157:                if (!units.equals("")) {
158:                    f = (Float) unitHash.get(units);
159:                    if (f == null) {
160:                        System.out.println(units
161:                                + " is not a known unit; 1 used instead.");
162:                        factor = 1;
163:                    } else {
164:                        factor = f.floatValue();
165:                    }
166:                } else {
167:                    factor = 1;
168:                }
169:
170:                f = new Float(flength * factor);
171:
172:                pixels = f.intValue() * sign;
173:
174:                return pixels;
175:            }
176:
177:            /**
178:             * <p>Find the string value of a stylesheet variable or parameter</p>
179:             *
180:             * <p>Returns the string value of <code>varName</code> in the current
181:             * <code>context</code>. Returns the empty string if the variable is
182:             * not defined.</p>
183:             *
184:             * @param context The current stylesheet context
185:             * @param varName The name of the variable (without the dollar sign)
186:             *
187:             * @return The string value of the variable
188:             */
189:            protected static String getVariable(Context context, String varName)
190:                    throws TransformerException {
191:                Value variable = null;
192:                String varString = null;
193:
194:                try {
195:                    variable = Extensions.evaluate(context, "$" + varName);
196:                    varString = variable.asString();
197:                    return varString;
198:                } catch (IllegalArgumentException e) {
199:                    System.out.println("Undefined variable: " + varName);
200:                    return "";
201:                }
202:            }
203:
204:            /**
205:             * <p>Setup the parameters associated with column width calculations</p>
206:             *
207:             * <p>This method queries the stylesheet for the variables
208:             * associated with table column widths. It is called automatically before
209:             * column widths are adjusted. The context is used to retrieve the values,
210:             * this allows templates to redefine these variables.</p>
211:             *
212:             * <p>The following variables are queried. If the variables do not
213:             * exist, builtin defaults will be used (but you may also get a bunch
214:             * of messages from the Java interpreter).</p>
215:             *
216:             * <dl>
217:             * <dt><code>nominal.table.width</code></dt>
218:             * <dd>The "normal" width for tables. This must be an absolute length.</dd>
219:             * <dt><code>table.width</code></dt>
220:             * <dd>The width for tables. This may be either an absolute
221:             * length or a percentage.</dd>
222:             * </dl>
223:             *
224:             * @param context The current stylesheet context
225:             *
226:             */
227:            private static void setupColumnWidths(Context context) {
228:                // Hardcoded defaults
229:                nominalWidth = 6 * pixelsPerInch;
230:                tableWidth = "100%";
231:
232:                String varString = null;
233:
234:                try {
235:                    // Get the stylesheet type
236:                    varString = getVariable(context, "stylesheet.result.type");
237:                    foStylesheet = varString.equals("fo");
238:
239:                    // Get the nominal table width
240:                    varString = getVariable(context, "nominal.table.width");
241:                    nominalWidth = convertLength(varString);
242:
243:                    // Get the table width
244:                    varString = getVariable(context, "table.width");
245:                    tableWidth = varString;
246:                } catch (TransformerException e) {
247:                    //nop, can't happen
248:                }
249:            }
250:
251:            /**
252:             * <p>Adjust column widths in an HTML table.</p>
253:             *
254:             * <p>The specification of column widths in CALS (a relative width
255:             * plus an optional absolute width) are incompatible with HTML column
256:             * widths. This method adjusts CALS column width specifiers in an
257:             * attempt to produce equivalent HTML specifiers.</p>
258:             *
259:             * <p>In order for this method to work, the CALS width specifications
260:             * should be placed in the "width" attribute of the &lt;col>s within
261:             * a &lt;colgroup>. Then the colgroup result tree fragment is passed
262:             * to this method.</p>
263:             *
264:             * <p>This method makes use of two parameters from the XSL stylesheet
265:             * that calls it: <code>nominal.table.width</code> and
266:             * <code>table.width</code>. The value of <code>nominal.table.width</code>
267:             * must be an absolute distance. The value of <code>table.width</code>
268:             * can be either absolute or relative.</p>
269:             *
270:             * <p>Presented with a mixture of relative and
271:             * absolute lengths, the table width is used to calculate
272:             * appropriate values. If the <code>table.width</code> is relative,
273:             * the nominal width is used for this calculation.</p>
274:             *
275:             * <p>There are three possible combinations of values:</p>
276:             *
277:             * <ol>
278:             * <li>There are no relative widths; in this case the absolute widths
279:             * are used in the HTML table.</li>
280:             * <li>There are no absolute widths; in this case the relative widths
281:             * are used in the HTML table.</li>
282:             * <li>There are a mixture of absolute and relative widths:
283:             *   <ol>
284:             *     <li>If the table width is absolute, all widths become absolute.</li>
285:             *     <li>If the table width is relative, make all the widths absolute
286:             *         relative to the nominal table width then turn them all
287:             *         back into relative widths.</li>
288:             *   </ol>
289:             * </li>
290:             * </ol>
291:             *
292:             * @param context The stylesheet context; supplied automatically by Saxon
293:             * @param rtf The result tree fragment containing the colgroup.
294:             *
295:             * @return The result tree fragment containing the adjusted colgroup.
296:             *
297:             */
298:            public static NodeSetValue adjustColumnWidths(Context context,
299:                    NodeSetValue rtf_ns) {
300:
301:                FragmentValue rtf = (FragmentValue) rtf_ns;
302:
303:                setupColumnWidths(context);
304:
305:                try {
306:                    Controller controller = context.getController();
307:                    NamePool namePool = controller.getNamePool();
308:
309:                    ColumnScanEmitter csEmitter = new ColumnScanEmitter(
310:                            namePool);
311:                    rtf.replay(csEmitter);
312:
313:                    int numColumns = csEmitter.columnCount();
314:                    String widths[] = csEmitter.columnWidths();
315:
316:                    float relTotal = 0;
317:                    float relParts[] = new float[numColumns];
318:
319:                    float absTotal = 0;
320:                    float absParts[] = new float[numColumns];
321:
322:                    for (int count = 0; count < numColumns; count++) {
323:                        String width = widths[count];
324:
325:                        int pos = width.indexOf("*");
326:                        if (pos >= 0) {
327:                            String relPart = width.substring(0, pos);
328:                            String absPart = width.substring(pos + 1);
329:
330:                            try {
331:                                float rel = Float.parseFloat(relPart);
332:                                relTotal += rel;
333:                                relParts[count] = rel;
334:                            } catch (NumberFormatException e) {
335:                                System.out.println(relPart
336:                                        + " is not a valid relative unit.");
337:                            }
338:
339:                            int pixels = 0;
340:                            if (absPart != null && !absPart.equals("")) {
341:                                pixels = convertLength(absPart);
342:                            }
343:
344:                            absTotal += pixels;
345:                            absParts[count] = pixels;
346:                        } else {
347:                            relParts[count] = 0;
348:
349:                            int pixels = 0;
350:                            if (width != null && !width.equals("")) {
351:                                pixels = convertLength(width);
352:                            }
353:
354:                            absTotal += pixels;
355:                            absParts[count] = pixels;
356:                        }
357:                    }
358:
359:                    // Ok, now we have the relative widths and absolute widths in
360:                    // two parallel arrays.
361:                    //
362:                    // - If there are no relative widths, output the absolute widths
363:                    // - If there are no absolute widths, output the relative widths
364:                    // - If there are a mixture of relative and absolute widths,
365:                    //   - If the table width is absolute, turn these all into absolute
366:                    //     widths.
367:                    //   - If the table width is relative, turn these all into absolute
368:                    //     widths in the nominalWidth and then turn them back into
369:                    //     percentages.
370:
371:                    if (relTotal == 0) {
372:                        for (int count = 0; count < numColumns; count++) {
373:                            Float f = new Float(absParts[count]);
374:                            if (foStylesheet) {
375:                                int pixels = f.intValue();
376:                                float inches = (float) pixels / pixelsPerInch;
377:                                widths[count] = inches + "in";
378:                            } else {
379:                                widths[count] = Integer.toString(f.intValue());
380:                            }
381:                        }
382:                    } else if (absTotal == 0) {
383:                        for (int count = 0; count < numColumns; count++) {
384:                            float rel = relParts[count] / relTotal * 100;
385:                            Float f = new Float(rel);
386:                            widths[count] = Integer.toString(f.intValue());
387:                        }
388:                        widths = correctRoundingError(widths);
389:                    } else {
390:                        int pixelWidth = nominalWidth;
391:
392:                        if (tableWidth.indexOf("%") <= 0) {
393:                            pixelWidth = convertLength(tableWidth);
394:                        }
395:
396:                        if (pixelWidth <= absTotal) {
397:                            System.out
398:                                    .println("Table is wider than table width.");
399:                        } else {
400:                            pixelWidth -= absTotal;
401:                        }
402:
403:                        absTotal = 0;
404:                        for (int count = 0; count < numColumns; count++) {
405:                            float rel = relParts[count] / relTotal * pixelWidth;
406:                            relParts[count] = rel + absParts[count];
407:                            absTotal += rel + absParts[count];
408:                        }
409:
410:                        if (tableWidth.indexOf("%") <= 0) {
411:                            for (int count = 0; count < numColumns; count++) {
412:                                Float f = new Float(relParts[count]);
413:                                if (foStylesheet) {
414:                                    int pixels = f.intValue();
415:                                    float inches = (float) pixels
416:                                            / pixelsPerInch;
417:                                    widths[count] = inches + "in";
418:                                } else {
419:                                    widths[count] = Integer.toString(f
420:                                            .intValue());
421:                                }
422:                            }
423:                        } else {
424:                            for (int count = 0; count < numColumns; count++) {
425:                                float rel = relParts[count] / absTotal * 100;
426:                                Float f = new Float(rel);
427:                                widths[count] = Integer.toString(f.intValue());
428:                            }
429:                            widths = correctRoundingError(widths);
430:                        }
431:                    }
432:
433:                    ColumnUpdateEmitter cuEmitter = new ColumnUpdateEmitter(
434:                            controller, namePool, widths);
435:
436:                    rtf.replay(cuEmitter);
437:                    return cuEmitter.getResultTreeFragment();
438:                } catch (TransformerException e) {
439:                    // This "can't" happen.
440:                    System.out
441:                            .println("Transformer Exception in adjustColumnWidths");
442:                    return rtf;
443:                }
444:            }
445:
446:            /**
447:             * Correct rounding errors introduced in calculating the width of each
448:             * column. Make sure they sum to 100% in the end.
449:             */
450:            protected static String[] correctRoundingError(String widths[]) {
451:                int totalWidth = 0;
452:
453:                for (int count = 0; count < widths.length; count++) {
454:                    try {
455:                        int width = Integer.parseInt(widths[count]);
456:                        totalWidth += width;
457:                    } catch (NumberFormatException nfe) {
458:                        // nop; "can't happen"
459:                    }
460:                }
461:
462:                float totalError = 100 - totalWidth;
463:                float columnError = totalError / widths.length;
464:                float error = 0;
465:
466:                for (int count = 0; count < widths.length; count++) {
467:                    try {
468:                        int width = Integer.parseInt(widths[count]);
469:                        error = error + columnError;
470:                        if (error >= 1.0) {
471:                            int adj = (int) Math.round(Math.floor(error));
472:                            error = error - (float) Math.floor(error);
473:                            width = width + adj;
474:                            widths[count] = Integer.toString(width) + "%";
475:                        } else {
476:                            widths[count] = Integer.toString(width) + "%";
477:                        }
478:                    } catch (NumberFormatException nfe) {
479:                        // nop; "can't happen"
480:                    }
481:                }
482:
483:                return widths;
484:            }
485:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.