Source Code Cross Referenced for DatatypeConverterImpl.java in  » 6.0-JDK-Modules-com.sun » xml » com » sun » xml » internal » bind » 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 » 6.0 JDK Modules com.sun » xml » com.sun.xml.internal.bind 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004:         *
005:         * This code is free software; you can redistribute it and/or modify it
006:         * under the terms of the GNU General Public License version 2 only, as
007:         * published by the Free Software Foundation.  Sun designates this
008:         * particular file as subject to the "Classpath" exception as provided
009:         * by Sun in the LICENSE file that accompanied this code.
010:         *
011:         * This code is distributed in the hope that it will be useful, but WITHOUT
012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014:         * version 2 for more details (a copy is included in the LICENSE file that
015:         * accompanied this code).
016:         *
017:         * You should have received a copy of the GNU General Public License version
018:         * 2 along with this work; if not, write to the Free Software Foundation,
019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020:         *
021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022:         * CA 95054 USA or visit www.sun.com if you need additional information or
023:         * have any questions.
024:         */
025:
026:        package com.sun.xml.internal.bind;
027:
028:        import java.math.BigDecimal;
029:        import java.math.BigInteger;
030:        import java.util.Calendar;
031:        import java.util.GregorianCalendar;
032:        import java.util.TimeZone;
033:
034:        import javax.xml.bind.DatatypeConverter;
035:        import javax.xml.bind.DatatypeConverterInterface;
036:        import javax.xml.datatype.DatatypeConfigurationException;
037:        import javax.xml.datatype.DatatypeFactory;
038:        import javax.xml.namespace.NamespaceContext;
039:        import javax.xml.namespace.QName;
040:
041:        import com.sun.xml.internal.bind.v2.TODO;
042:
043:        /**
044:         * This class is the JAXB RI's default implementation of the 
045:         * {@link DatatypeConverterInterface}.
046:         *
047:         * <p>
048:         * When client apps specify the use of the static print/parse
049:         * methods in {@link DatatypeConverter}, it will delegate
050:         * to this class.
051:         *
052:         * <p>
053:         * This class is responsible for whitespace normalization.
054:         *
055:         * @author <ul><li>Ryan Shoemaker, Sun Microsystems, Inc.</li></ul>
056:         * @version $Revision: 1.8 $
057:         * @since JAXB1.0
058:         */
059:        public final class DatatypeConverterImpl implements 
060:                DatatypeConverterInterface {
061:
062:            /**
063:             * To avoid re-creating instances, we cache one instance.
064:             */
065:            public static final DatatypeConverterInterface theInstance = new DatatypeConverterImpl();
066:
067:            protected DatatypeConverterImpl() {
068:            }
069:
070:            public String parseString(String lexicalXSDString) {
071:                return lexicalXSDString;
072:            }
073:
074:            public BigInteger parseInteger(String lexicalXSDInteger) {
075:                return _parseInteger(lexicalXSDInteger);
076:            }
077:
078:            public static BigInteger _parseInteger(CharSequence s) {
079:                return new BigInteger(removeOptionalPlus(
080:                        WhiteSpaceProcessor.trim(s)).toString());
081:            }
082:
083:            public String printInteger(BigInteger val) {
084:                return _printInteger(val);
085:            }
086:
087:            public static String _printInteger(BigInteger val) {
088:                return val.toString();
089:            }
090:
091:            public int parseInt(String s) {
092:                return _parseInt(s);
093:            }
094:
095:            /**
096:             * Faster but less robust String->int conversion.
097:             *
098:             * Note that:
099:             * <ol>
100:             *  <li>XML Schema allows '+', but {@link Integer#valueOf(String)} is not.
101:             *  <li>XML Schema allows leading and trailing (but not in-between) whitespaces..
102:             *      {@link Integer#valueOf(String)} doesn't allow any.
103:             * </ol>
104:             */
105:            public static int _parseInt(CharSequence s) {
106:                int len = s.length();
107:                int sign = 1;
108:
109:                int r = 0;
110:
111:                for (int i = 0; i < len; i++) {
112:                    char ch = s.charAt(i);
113:                    if (WhiteSpaceProcessor.isWhiteSpace(ch)) {
114:                        // skip whitespace
115:                    } else if ('0' <= ch && ch <= '9') {
116:                        r = r * 10 + (ch - '0');
117:                    } else if (ch == '-') {
118:                        sign = -1;
119:                    } else if (ch == '+') {
120:                        ; // noop
121:                    } else
122:                        throw new NumberFormatException("Not a number: " + s);
123:                }
124:
125:                return r * sign;
126:            }
127:
128:            public long parseLong(String lexicalXSLong) {
129:                return _parseLong(lexicalXSLong);
130:            }
131:
132:            public static long _parseLong(CharSequence s) {
133:                return Long.valueOf(removeOptionalPlus(
134:                        WhiteSpaceProcessor.trim(s)).toString());
135:            }
136:
137:            public short parseShort(String lexicalXSDShort) {
138:                return _parseShort(lexicalXSDShort);
139:            }
140:
141:            public static final short _parseShort(CharSequence s) {
142:                return (short) _parseInt(s);
143:            }
144:
145:            public String printShort(short val) {
146:                return _printShort(val);
147:            }
148:
149:            public static String _printShort(short val) {
150:                return String.valueOf(val);
151:            }
152:
153:            public BigDecimal parseDecimal(String content) {
154:                return _parseDecimal(content);
155:            }
156:
157:            public static BigDecimal _parseDecimal(CharSequence content) {
158:                content = WhiteSpaceProcessor.trim(content);
159:
160:                return new BigDecimal(content.toString());
161:
162:                // from purely XML Schema perspective,
163:                // this implementation has a problem, since 
164:                // in xs:decimal "1.0" and "1" is equal whereas the above
165:                // code will return different values for those two forms.
166:                //
167:                // the code was originally using com.sun.msv.datatype.xsd.NumberType.load,
168:                // but a profiling showed that the process of normalizing "1.0" into "1"
169:                // could take non-trivial time.
170:                //
171:                // also, from the user's point of view, one might be surprised if
172:                // 1 (not 1.0) is returned from "1.000" 
173:            }
174:
175:            public float parseFloat(String lexicalXSDFloat) {
176:                return _parseFloat(lexicalXSDFloat);
177:            }
178:
179:            public static float _parseFloat(CharSequence _val) {
180:                String s = WhiteSpaceProcessor.trim(_val).toString();
181:                /* Incompatibilities of XML Schema's float "xfloat" and Java's float "jfloat"
182:
183:                 * jfloat.valueOf ignores leading and trailing whitespaces,
184:                      whereas this is not allowed in xfloat.
185:                 * jfloat.valueOf allows "float type suffix" (f, F) to be
186:                      appended after float literal (e.g., 1.52e-2f), whereare
187:                      this is not the case of xfloat.
188:
189:                    gray zone
190:                    ---------
191:                 * jfloat allows ".523". And there is no clear statement that mentions
192:                      this case in xfloat. Although probably this is allowed.
193:                 *
194:                 */
195:
196:                if (s.equals("NaN"))
197:                    return Float.NaN;
198:                if (s.equals("INF"))
199:                    return Float.POSITIVE_INFINITY;
200:                if (s.equals("-INF"))
201:                    return Float.NEGATIVE_INFINITY;
202:
203:                if (s.length() == 0 || !isDigitOrPeriodOrSign(s.charAt(0))
204:                        || !isDigitOrPeriodOrSign(s.charAt(s.length() - 1)))
205:                    throw new NumberFormatException();
206:
207:                // these screening process is necessary due to the wobble of Float.valueOf method
208:                return Float.parseFloat(s);
209:            }
210:
211:            public String printFloat(float v) {
212:                return _printFloat(v);
213:            }
214:
215:            public static String _printFloat(float v) {
216:                if (v == Float.NaN)
217:                    return "NaN";
218:                if (v == Float.POSITIVE_INFINITY)
219:                    return "INF";
220:                if (v == Float.NEGATIVE_INFINITY)
221:                    return "-INF";
222:                return String.valueOf(v);
223:            }
224:
225:            public double parseDouble(String lexicalXSDDouble) {
226:                return _parseDouble(lexicalXSDDouble);
227:            }
228:
229:            public static double _parseDouble(CharSequence _val) {
230:                String val = WhiteSpaceProcessor.trim(_val).toString();
231:
232:                if (val.equals("NaN"))
233:                    return Double.NaN;
234:                if (val.equals("INF"))
235:                    return Double.POSITIVE_INFINITY;
236:                if (val.equals("-INF"))
237:                    return Double.NEGATIVE_INFINITY;
238:
239:                if (val.length() == 0 || !isDigitOrPeriodOrSign(val.charAt(0))
240:                        || !isDigitOrPeriodOrSign(val.charAt(val.length() - 1)))
241:                    throw new NumberFormatException(val);
242:
243:                // these screening process is necessary due to the wobble of Float.valueOf method
244:                return Double.parseDouble(val);
245:            }
246:
247:            public boolean parseBoolean(String lexicalXSDBoolean) {
248:                return _parseBoolean(lexicalXSDBoolean);
249:            }
250:
251:            public static boolean _parseBoolean(CharSequence literal) {
252:                int i = 0;
253:                int len = literal.length();
254:                char ch;
255:                do {
256:                    ch = literal.charAt(i++);
257:                } while (WhiteSpaceProcessor.isWhiteSpace(ch) && i < len);
258:
259:                // if we are strict about errors, check i==len. and report an error
260:
261:                if (ch == 't' || ch == '1')
262:                    return true;
263:                if (ch == 'f' || ch == '0')
264:                    return false;
265:                TODO.checkSpec("issue #42");
266:                return false;
267:            }
268:
269:            public String printBoolean(boolean val) {
270:                return val ? "true" : "false";
271:            }
272:
273:            public static String _printBoolean(boolean val) {
274:                return val ? "true" : "false";
275:            }
276:
277:            public byte parseByte(String lexicalXSDByte) {
278:                return _parseByte(lexicalXSDByte);
279:            }
280:
281:            public static byte _parseByte(CharSequence literal) {
282:                return (byte) _parseInt(literal);
283:            }
284:
285:            public String printByte(byte val) {
286:                return _printByte(val);
287:            }
288:
289:            public static String _printByte(byte val) {
290:                return String.valueOf(val);
291:            }
292:
293:            public QName parseQName(String lexicalXSDQName, NamespaceContext nsc) {
294:                return _parseQName(lexicalXSDQName, nsc);
295:            }
296:
297:            /**
298:             * @return null if fails to convert.
299:             */
300:            public static QName _parseQName(CharSequence text,
301:                    NamespaceContext nsc) {
302:                int length = text.length();
303:
304:                // trim whitespace
305:                int start = 0;
306:                while (start < length
307:                        && WhiteSpaceProcessor.isWhiteSpace(text.charAt(start)))
308:                    start++;
309:
310:                int end = length;
311:                while (end > start
312:                        && WhiteSpaceProcessor.isWhiteSpace(text
313:                                .charAt(end - 1)))
314:                    end--;
315:
316:                if (end == start)
317:                    throw new IllegalArgumentException("input is empty");
318:
319:                String uri;
320:                String localPart;
321:                String prefix;
322:
323:                // search ':'
324:                int idx = start + 1; // no point in searching the first char. that's not valid.
325:                while (idx < end && text.charAt(idx) != ':')
326:                    idx++;
327:
328:                if (idx == end) {
329:                    uri = nsc.getNamespaceURI("");
330:                    localPart = text.subSequence(start, end).toString();
331:                    prefix = "";
332:                } else {
333:                    // Prefix exists, check everything
334:                    prefix = text.subSequence(start, idx).toString();
335:                    localPart = text.subSequence(idx + 1, end).toString();
336:                    uri = nsc.getNamespaceURI(prefix);
337:                    // uri can never be null according to javadoc,
338:                    // but some users reported that there are implementations that return null.
339:                    if (uri == null || uri.length() == 0) // crap. the NamespaceContext interface is broken.
340:                        // error: unbound prefix
341:                        throw new IllegalArgumentException("prefix " + prefix
342:                                + " is not bound to a namespace");
343:                }
344:
345:                return new QName(uri, localPart, prefix);
346:            }
347:
348:            public Calendar parseDateTime(String lexicalXSDDateTime) {
349:                return _parseDateTime(lexicalXSDDateTime);
350:            }
351:
352:            public static GregorianCalendar _parseDateTime(CharSequence s) {
353:                String val = WhiteSpaceProcessor.trim(s).toString();
354:                return datatypeFactory.newXMLGregorianCalendar(val)
355:                        .toGregorianCalendar();
356:            }
357:
358:            public String printDateTime(Calendar val) {
359:                return _printDateTime(val);
360:            }
361:
362:            public static String _printDateTime(Calendar val) {
363:                return CalendarFormatter.doFormat("%Y-%M-%DT%h:%m:%s%z", val);
364:            }
365:
366:            public byte[] parseBase64Binary(String lexicalXSDBase64Binary) {
367:                return _parseBase64Binary(lexicalXSDBase64Binary);
368:            }
369:
370:            public byte[] parseHexBinary(String s) {
371:                final int len = s.length();
372:
373:                // "111" is not a valid hex encoding.
374:                if (len % 2 != 0)
375:                    return null;
376:
377:                byte[] out = new byte[len / 2];
378:
379:                for (int i = 0; i < len; i += 2) {
380:                    int h = hexToBin(s.charAt(i));
381:                    int l = hexToBin(s.charAt(i + 1));
382:                    if (h == -1 || l == -1)
383:                        return null; // illegal character
384:
385:                    out[i / 2] = (byte) (h * 16 + l);
386:                }
387:
388:                return out;
389:            }
390:
391:            private static int hexToBin(char ch) {
392:                if ('0' <= ch && ch <= '9')
393:                    return ch - '0';
394:                if ('A' <= ch && ch <= 'F')
395:                    return ch - 'A' + 10;
396:                if ('a' <= ch && ch <= 'f')
397:                    return ch - 'a' + 10;
398:                return -1;
399:            }
400:
401:            private static final char[] hexCode = "0123456789ABCDEF"
402:                    .toCharArray();
403:
404:            public String printHexBinary(byte[] data) {
405:                StringBuilder r = new StringBuilder(data.length * 2);
406:                for (byte b : data) {
407:                    r.append(hexCode[(b >> 4) & 0xF]);
408:                    r.append(hexCode[(b & 0xF)]);
409:                }
410:                return r.toString();
411:            }
412:
413:            public long parseUnsignedInt(String lexicalXSDUnsignedInt) {
414:                return _parseLong(lexicalXSDUnsignedInt);
415:            }
416:
417:            public String printUnsignedInt(long val) {
418:                return _printLong(val);
419:            }
420:
421:            public int parseUnsignedShort(String lexicalXSDUnsignedShort) {
422:                return _parseInt(lexicalXSDUnsignedShort);
423:            }
424:
425:            public Calendar parseTime(String lexicalXSDTime) {
426:                return datatypeFactory.newXMLGregorianCalendar(lexicalXSDTime)
427:                        .toGregorianCalendar();
428:            }
429:
430:            public String printTime(Calendar val) {
431:                return CalendarFormatter.doFormat("%h:%m:%s%z", val);
432:            }
433:
434:            public Calendar parseDate(String lexicalXSDDate) {
435:                return datatypeFactory.newXMLGregorianCalendar(lexicalXSDDate)
436:                        .toGregorianCalendar();
437:            }
438:
439:            public String printDate(Calendar val) {
440:
441:                return CalendarFormatter
442:                        .doFormat((new StringBuilder("%Y-%M-%D").append("%z"))
443:                                .toString(), val);
444:            }
445:
446:            public String parseAnySimpleType(String lexicalXSDAnySimpleType) {
447:                return lexicalXSDAnySimpleType;
448:                //        return (String)SimpleURType.theInstance._createValue( lexicalXSDAnySimpleType, null );
449:            }
450:
451:            public String printString(String val) {
452:                //        return StringType.theInstance.convertToLexicalValue( val, null );
453:                return val;
454:            }
455:
456:            public String printInt(int val) {
457:                return _printInt(val);
458:            }
459:
460:            public static String _printInt(int val) {
461:                return String.valueOf(val);
462:            }
463:
464:            public String printLong(long val) {
465:                return _printLong(val);
466:            }
467:
468:            public static String _printLong(long val) {
469:                return String.valueOf(val);
470:            }
471:
472:            public String printDecimal(BigDecimal val) {
473:                return _printDecimal(val);
474:            }
475:
476:            public static String _printDecimal(BigDecimal val) {
477:                return val.toString();
478:            }
479:
480:            public String printDouble(double v) {
481:                return _printDouble(v);
482:            }
483:
484:            public static String _printDouble(double v) {
485:                if (v == Double.NaN)
486:                    return "NaN";
487:                if (v == Double.POSITIVE_INFINITY)
488:                    return "INF";
489:                if (v == Double.NEGATIVE_INFINITY)
490:                    return "-INF";
491:                return String.valueOf(v);
492:            }
493:
494:            public String printQName(QName val, NamespaceContext nsc) {
495:                return _printQName(val, nsc);
496:            }
497:
498:            public static String _printQName(QName val, NamespaceContext nsc) {
499:                // Double-check
500:                String qname;
501:                String prefix = nsc.getPrefix(val.getNamespaceURI());
502:                String localPart = val.getLocalPart();
503:
504:                if (prefix == null || prefix.length() == 0) { // be defensive
505:                    qname = localPart;
506:                } else {
507:                    qname = prefix + ':' + localPart;
508:                }
509:
510:                return qname;
511:            }
512:
513:            public String printBase64Binary(byte[] val) {
514:                return _printBase64Binary(val);
515:            }
516:
517:            public String printUnsignedShort(int val) {
518:                return String.valueOf(val);
519:            }
520:
521:            public String printAnySimpleType(String val) {
522:                return val;
523:            }
524:
525:            /**
526:             * Just return the string passed as a parameter but
527:             * installs an instance of this class as the DatatypeConverter
528:             * implementation. Used from static fixed value initializers.
529:             */
530:            public static String installHook(String s) {
531:                DatatypeConverter.setDatatypeConverter(theInstance);
532:                return s;
533:            }
534:
535:            // base64 decoder
536:            //====================================
537:
538:            private static final byte[] decodeMap = initDecodeMap();
539:            private static final byte PADDING = 127;
540:
541:            private static byte[] initDecodeMap() {
542:                byte[] map = new byte[128];
543:                int i;
544:                for (i = 0; i < 128; i++)
545:                    map[i] = -1;
546:
547:                for (i = 'A'; i <= 'Z'; i++)
548:                    map[i] = (byte) (i - 'A');
549:                for (i = 'a'; i <= 'z'; i++)
550:                    map[i] = (byte) (i - 'a' + 26);
551:                for (i = '0'; i <= '9'; i++)
552:                    map[i] = (byte) (i - '0' + 52);
553:                map['+'] = 62;
554:                map['/'] = 63;
555:                map['='] = PADDING;
556:
557:                return map;
558:            }
559:
560:            /**
561:             * computes the length of binary data.
562:             *
563:             * This function also performs format check.
564:             * @return    -1        if format is illegal.
565:             *
566:             */
567:            private static int calcLength(String text) {
568:                final int len = text.length();
569:                int base64count = 0;
570:                int i;
571:
572:                for (i = 0; i < len; i++) {
573:                    char ch = text.charAt(i);
574:                    if (ch == '=') // decodeMap['=']!=-1, so we have to check this first.
575:                        break;
576:                    if (ch >= 128)
577:                        return -1; // incorrect character
578:                    if (decodeMap[ch] != -1)
579:                        base64count++;
580:                }
581:
582:                return (base64count / 4) * 3
583:                        + Math.max(0, (base64count % 4) - 1);
584:            }
585:
586:            /**
587:             * @param text
588:             *      base64Binary data is likely to be long, and decoding requires
589:             *      each character to be accessed twice (once for counting length, another
590:             *      for decoding.)
591:             *
592:             *      A benchmark showed that taking {@link String} is faster, presumably
593:             *      because JIT can inline a lot of string access (with data of 1K chars, it was twice as fast)
594:             */
595:            public static byte[] _parseBase64Binary(String text) {
596:                final int outlen = calcLength(text);
597:                if (outlen == -1)
598:                    return null;
599:                final byte[] out = new byte[outlen];
600:                int o = 0;
601:
602:                final int len = text.length();
603:                int i;
604:
605:                final byte[] quadruplet = new byte[4];
606:                int q = 0;
607:
608:                // convert each quadruplet to three bytes.
609:                for (i = 0; i < len; i++) {
610:                    char ch = text.charAt(i);
611:                    byte v = decodeMap[ch];
612:                    if (v != -1)
613:                        quadruplet[q++] = v;
614:
615:                    if (q == 4) {
616:                        // quadruplet is now filled.
617:                        out[o++] = (byte) ((quadruplet[0] << 2) | (quadruplet[1] >> 4));
618:                        if (quadruplet[2] != PADDING)
619:                            out[o++] = (byte) ((quadruplet[1] << 4) | (quadruplet[2] >> 2));
620:                        if (quadruplet[3] != PADDING)
621:                            out[o++] = (byte) ((quadruplet[2] << 6) | (quadruplet[3]));
622:                        q = 0;
623:                    }
624:                }
625:
626:                return out;
627:            }
628:
629:            private static final char[] encodeMap = initEncodeMap();
630:
631:            private static char[] initEncodeMap() {
632:                char[] map = new char[64];
633:                int i;
634:                for (i = 0; i < 26; i++)
635:                    map[i] = (char) ('A' + i);
636:                for (i = 26; i < 52; i++)
637:                    map[i] = (char) ('a' + (i - 26));
638:                for (i = 52; i < 62; i++)
639:                    map[i] = (char) ('0' + (i - 52));
640:                map[62] = '+';
641:                map[63] = '/';
642:
643:                return map;
644:            }
645:
646:            public static char encode(int i) {
647:                return encodeMap[i & 0x3F];
648:            }
649:
650:            public static byte encodeByte(int i) {
651:                return (byte) encodeMap[i & 0x3F];
652:            }
653:
654:            public static String _printBase64Binary(byte[] input) {
655:                return _printBase64Binary(input, 0, input.length);
656:            }
657:
658:            public static String _printBase64Binary(byte[] input, int offset,
659:                    int len) {
660:                char[] buf = new char[((len + 2) / 3) * 4];
661:                int ptr = _printBase64Binary(input, offset, len, buf, 0);
662:                assert ptr == buf.length;
663:                return new String(buf);
664:            }
665:
666:            /**
667:             * Encodes a byte array into a char array by doing base64 encoding.
668:             *
669:             * The caller must supply a big enough buffer.
670:             *
671:             * @return
672:             *      the value of {@code ptr+((len+2)/3)*4}, which is the new offset
673:             *      in the output buffer where the further bytes should be placed.
674:             */
675:            public static int _printBase64Binary(byte[] input, int offset,
676:                    int len, char[] buf, int ptr) {
677:                for (int i = offset; i < len; i += 3) {
678:                    switch (len - i) {
679:                    case 1:
680:                        buf[ptr++] = encode(input[i] >> 2);
681:                        buf[ptr++] = encode(((input[i]) & 0x3) << 4);
682:                        buf[ptr++] = '=';
683:                        buf[ptr++] = '=';
684:                        break;
685:                    case 2:
686:                        buf[ptr++] = encode(input[i] >> 2);
687:                        buf[ptr++] = encode(((input[i] & 0x3) << 4)
688:                                | ((input[i + 1] >> 4) & 0xF));
689:                        buf[ptr++] = encode((input[i + 1] & 0xF) << 2);
690:                        buf[ptr++] = '=';
691:                        break;
692:                    default:
693:                        buf[ptr++] = encode(input[i] >> 2);
694:                        buf[ptr++] = encode(((input[i] & 0x3) << 4)
695:                                | ((input[i + 1] >> 4) & 0xF));
696:                        buf[ptr++] = encode(((input[i + 1] & 0xF) << 2)
697:                                | ((input[i + 2] >> 6) & 0x3));
698:                        buf[ptr++] = encode(input[i + 2] & 0x3F);
699:                        break;
700:                    }
701:                }
702:                return ptr;
703:            }
704:
705:            /**
706:             * Encodes a byte array into another byte array by first doing base64 encoding
707:             * then encoding the result in ASCII.
708:             *
709:             * The caller must supply a big enough buffer.
710:             *
711:             * @return
712:             *      the value of {@code ptr+((len+2)/3)*4}, which is the new offset
713:             *      in the output buffer where the further bytes should be placed.
714:             */
715:            public static int _printBase64Binary(byte[] input, int offset,
716:                    int len, byte[] out, int ptr) {
717:                byte[] buf = out;
718:                int max = len + offset;
719:                for (int i = offset; i < max; i += 3) {
720:                    switch (max - i) {
721:                    case 1:
722:                        buf[ptr++] = encodeByte(input[i] >> 2);
723:                        buf[ptr++] = encodeByte(((input[i]) & 0x3) << 4);
724:                        buf[ptr++] = '=';
725:                        buf[ptr++] = '=';
726:                        break;
727:                    case 2:
728:                        buf[ptr++] = encodeByte(input[i] >> 2);
729:                        buf[ptr++] = encodeByte(((input[i] & 0x3) << 4)
730:                                | ((input[i + 1] >> 4) & 0xF));
731:                        buf[ptr++] = encodeByte((input[i + 1] & 0xF) << 2);
732:                        buf[ptr++] = '=';
733:                        break;
734:                    default:
735:                        buf[ptr++] = encodeByte(input[i] >> 2);
736:                        buf[ptr++] = encodeByte(((input[i] & 0x3) << 4)
737:                                | ((input[i + 1] >> 4) & 0xF));
738:                        buf[ptr++] = encodeByte(((input[i + 1] & 0xF) << 2)
739:                                | ((input[i + 2] >> 6) & 0x3));
740:                        buf[ptr++] = encodeByte(input[i + 2] & 0x3F);
741:                        break;
742:                    }
743:                }
744:
745:                return ptr;
746:            }
747:
748:            private static CharSequence removeOptionalPlus(CharSequence s) {
749:                int len = s.length();
750:
751:                if (len <= 1 || s.charAt(0) != '+')
752:                    return s;
753:
754:                s = s.subSequence(1, len);
755:                char ch = s.charAt(0);
756:                if ('0' <= ch && ch <= '9')
757:                    return s;
758:                if ('.' == ch)
759:                    return s;
760:
761:                throw new NumberFormatException();
762:            }
763:
764:            private static boolean isDigitOrPeriodOrSign(char ch) {
765:                if ('0' <= ch && ch <= '9')
766:                    return true;
767:                if (ch == '+' || ch == '-' || ch == '.')
768:                    return true;
769:                return false;
770:            }
771:
772:            private static final DatatypeFactory datatypeFactory;
773:
774:            static {
775:                try {
776:                    datatypeFactory = DatatypeFactory.newInstance();
777:                } catch (DatatypeConfigurationException e) {
778:                    throw new Error(e);
779:                }
780:            }
781:
782:            private static final class CalendarFormatter {
783:                public static String doFormat(String format, Calendar cal)
784:                        throws IllegalArgumentException {
785:                    int fidx = 0;
786:                    int flen = format.length();
787:                    StringBuilder buf = new StringBuilder();
788:
789:                    while (fidx < flen) {
790:                        char fch = format.charAt(fidx++);
791:
792:                        if (fch != '%') { // not a meta character
793:                            buf.append(fch);
794:                            continue;
795:                        }
796:
797:                        // seen meta character. we don't do error check against the format
798:                        switch (format.charAt(fidx++)) {
799:                        case 'Y': // year
800:                            formatYear(cal, buf);
801:                            break;
802:
803:                        case 'M': // month
804:                            formatMonth(cal, buf);
805:                            break;
806:
807:                        case 'D': // days
808:                            formatDays(cal, buf);
809:                            break;
810:
811:                        case 'h': // hours
812:                            formatHours(cal, buf);
813:                            break;
814:
815:                        case 'm': // minutes
816:                            formatMinutes(cal, buf);
817:                            break;
818:
819:                        case 's': // parse seconds.
820:                            formatSeconds(cal, buf);
821:                            break;
822:
823:                        case 'z': // time zone
824:                            formatTimeZone(cal, buf);
825:                            break;
826:
827:                        default:
828:                            // illegal meta character. impossible.
829:                            throw new InternalError();
830:                        }
831:                    }
832:
833:                    return buf.toString();
834:                }
835:
836:                private static void formatYear(Calendar cal, StringBuilder buf) {
837:                    int year = cal.get(Calendar.YEAR);
838:
839:                    String s;
840:                    if (year <= 0) // negative value
841:                        s = Integer.toString(1 - year);
842:                    else
843:                        // positive value
844:                        s = Integer.toString(year);
845:
846:                    while (s.length() < 4)
847:                        s = '0' + s;
848:                    if (year <= 0)
849:                        s = '-' + s;
850:
851:                    buf.append(s);
852:                }
853:
854:                private static void formatMonth(Calendar cal, StringBuilder buf) {
855:                    formatTwoDigits(cal.get(Calendar.MONTH) + 1, buf);
856:                }
857:
858:                private static void formatDays(Calendar cal, StringBuilder buf) {
859:                    formatTwoDigits(cal.get(Calendar.DAY_OF_MONTH), buf);
860:                }
861:
862:                private static void formatHours(Calendar cal, StringBuilder buf) {
863:                    formatTwoDigits(cal.get(Calendar.HOUR_OF_DAY), buf);
864:                }
865:
866:                private static void formatMinutes(Calendar cal,
867:                        StringBuilder buf) {
868:                    formatTwoDigits(cal.get(Calendar.MINUTE), buf);
869:                }
870:
871:                private static void formatSeconds(Calendar cal,
872:                        StringBuilder buf) {
873:                    formatTwoDigits(cal.get(Calendar.SECOND), buf);
874:                    if (cal.isSet(Calendar.MILLISECOND)) { // milliseconds
875:                        int n = cal.get(Calendar.MILLISECOND);
876:                        if (n != 0) {
877:                            String ms = Integer.toString(n);
878:                            while (ms.length() < 3)
879:                                ms = '0' + ms; // left 0 paddings.
880:
881:                            buf.append('.');
882:                            buf.append(ms);
883:                        }
884:                    }
885:                }
886:
887:                /** formats time zone specifier. */
888:                private static void formatTimeZone(Calendar cal,
889:                        StringBuilder buf) {
890:                    TimeZone tz = cal.getTimeZone();
891:
892:                    if (tz == null)
893:                        return;
894:
895:                    // otherwise print out normally.
896:                    int offset;
897:                    if (tz.inDaylightTime(cal.getTime())) {
898:                        offset = tz.getRawOffset()
899:                                + (tz.useDaylightTime() ? 3600000 : 0);
900:                    } else {
901:                        offset = tz.getRawOffset();
902:                    }
903:
904:                    if (offset >= 0)
905:                        buf.append('+');
906:                    else {
907:                        buf.append('-');
908:                        offset *= -1;
909:                    }
910:
911:                    offset /= 60 * 1000; // offset is in milli-seconds
912:
913:                    formatTwoDigits(offset / 60, buf);
914:                    buf.append(':');
915:                    formatTwoDigits(offset % 60, buf);
916:                }
917:
918:                /** formats Integer into two-character-wide string. */
919:                private static final void formatTwoDigits(int n,
920:                        StringBuilder buf) {
921:                    // n is always non-negative.
922:                    if (n < 10)
923:                        buf.append('0');
924:                    buf.append(n);
925:                }
926:            }
927:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.