Home » xmlbeans-2.5.0-src » org.apache.xmlbeans.impl » util » [javadoc | source]

    1   /*   Copyright 2004 The Apache Software Foundation
    2    *
    3    *   Licensed under the Apache License, Version 2.0 (the "License");
    4    *   you may not use this file except in compliance with the License.
    5    *   You may obtain a copy of the License at
    6    *
    7    *       http://www.apache.org/licenses/LICENSE-2.0
    8    *
    9    *   Unless required by applicable law or agreed to in writing, software
   10    *   distributed under the License is distributed on an "AS IS" BASIS,
   11    *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   12    *   See the License for the specific language governing permissions and
   13    *  limitations under the License.
   14    */
   15   
   16   package org.apache.xmlbeans.impl.util;
   17   
   18   import org.apache.xmlbeans.GDate;
   19   import org.apache.xmlbeans.GDateBuilder;
   20   import org.apache.xmlbeans.GDateSpecification;
   21   import org.apache.xmlbeans.SchemaType;
   22   import org.apache.xmlbeans.XmlCalendar;
   23   import org.apache.xmlbeans.XmlError;
   24   import org.apache.xmlbeans.impl.common.InvalidLexicalValueException;
   25   
   26   import javax.xml.namespace.NamespaceContext;
   27   import javax.xml.namespace.QName;
   28   import java.math.BigDecimal;
   29   import java.math.BigInteger;
   30   import java.util.Calendar;
   31   import java.util.Collection;
   32   import java.util.Date;
   33   import java.net.URI;
   34   
   35   public final class XsTypeConverter
   36   {
   37       private static final String POS_INF_LEX = "INF";
   38       private static final String NEG_INF_LEX = "-INF";
   39       private static final String NAN_LEX = "NaN";
   40   
   41       private static final char NAMESPACE_SEP = ':';
   42       private static final String EMPTY_PREFIX = "";
   43       private static final BigDecimal DECIMAL__ZERO = new BigDecimal(0.0);
   44   
   45       // See Section 2.4.3 of FRC2396  http://www.ietf.org/rfc/rfc2396.txt
   46       private static final String[] URI_CHARS_TO_BE_REPLACED = {" "  , "{"  , "}"  , "|"  , "\\" , "^"  , "["  , "]"  , "`"  };
   47       private static final String[] URI_CHARS_REPLACED_WITH  = {"%20", "%7b", "%7d", "%7c", "%5c", "%5e", "%5b", "%5d", "%60"};
   48   
   49       // ======================== float ========================
   50       public static float lexFloat(CharSequence cs)
   51           throws NumberFormatException
   52       {
   53           final String v = cs.toString();
   54           try {
   55               //current jdk impl of parseFloat calls trim() on the string.
   56               //Any other space is illegal anyway, whether there are one or more spaces.
   57               //so no need to do a collapse pass through the string.
   58               if (cs.length() > 0) {
   59                   char ch = cs.charAt(cs.length() - 1);
   60                   if (ch == 'f' || ch == 'F') {
   61                       if (cs.charAt(cs.length() - 2) != 'N')
   62                           throw new NumberFormatException("Invalid char '" + ch + "' in float.");
   63                   }
   64               }
   65               return Float.parseFloat(v);
   66           }
   67           catch (NumberFormatException e) {
   68               if (v.equals(POS_INF_LEX)) return Float.POSITIVE_INFINITY;
   69               if (v.equals(NEG_INF_LEX)) return Float.NEGATIVE_INFINITY;
   70               if (v.equals(NAN_LEX)) return Float.NaN;
   71   
   72               throw e;
   73           }
   74       }
   75   
   76       public static float lexFloat(CharSequence cs, Collection errors)
   77       {
   78           try {
   79               return lexFloat(cs);
   80           }
   81           catch (NumberFormatException e) {
   82               String msg = "invalid float: " + cs;
   83               errors.add(XmlError.forMessage(msg));
   84   
   85               return Float.NaN;
   86           }
   87       }
   88   
   89       public static String printFloat(float value)
   90       {
   91           if (value == Float.POSITIVE_INFINITY)
   92               return POS_INF_LEX;
   93           else if (value == Float.NEGATIVE_INFINITY)
   94               return NEG_INF_LEX;
   95           else if (Float.isNaN(value))
   96               return NAN_LEX;
   97           else
   98               return Float.toString(value);
   99       }
  100   
  101   
  102       // ======================== double ========================
  103       public static double lexDouble(CharSequence cs)
  104           throws NumberFormatException
  105       {
  106           final String v = cs.toString();
  107   
  108           try {
  109               //current jdk impl of parseDouble calls trim() on the string.
  110               //Any other space is illegal anyway, whether there are one or more spaces.
  111               //so no need to do a collapse pass through the string.
  112               if (cs.length() > 0) {
  113                   char ch = cs.charAt(cs.length() - 1);
  114                   if (ch == 'd' || ch == 'D')
  115                       throw new NumberFormatException("Invalid char '" + ch + "' in double.");
  116               }
  117               return Double.parseDouble(v);
  118           }
  119           catch (NumberFormatException e) {
  120               if (v.equals(POS_INF_LEX)) return Double.POSITIVE_INFINITY;
  121               if (v.equals(NEG_INF_LEX)) return Double.NEGATIVE_INFINITY;
  122               if (v.equals(NAN_LEX)) return Double.NaN;
  123   
  124               throw e;
  125           }
  126       }
  127   
  128       public static double lexDouble(CharSequence cs, Collection errors)
  129       {
  130           try {
  131               return lexDouble(cs);
  132           }
  133           catch (NumberFormatException e) {
  134               String msg = "invalid double: " + cs;
  135               errors.add(XmlError.forMessage(msg));
  136   
  137               return Double.NaN;
  138           }
  139       }
  140   
  141       public static String printDouble(double value)
  142       {
  143           if (value == Double.POSITIVE_INFINITY)
  144               return POS_INF_LEX;
  145           else if (value == Double.NEGATIVE_INFINITY)
  146               return NEG_INF_LEX;
  147           else if (Double.isNaN(value))
  148               return NAN_LEX;
  149           else
  150               return Double.toString(value);
  151       }
  152   
  153   
  154       // ======================== decimal ========================
  155       public static BigDecimal lexDecimal(CharSequence cs)
  156           throws NumberFormatException
  157       {
  158           final String v = cs.toString();
  159   
  160           //TODO: review this
  161           //NOTE: we trim unneeded zeros from the string because
  162           //java.math.BigDecimal considers them significant for its
  163           //equals() method, but the xml value
  164           //space does not consider them significant.
  165           //See http://www.w3.org/2001/05/xmlschema-errata#e2-44
  166           return new BigDecimal(trimTrailingZeros(v));
  167       }
  168   
  169       public static BigDecimal lexDecimal(CharSequence cs, Collection errors)
  170       {
  171           try {
  172               return lexDecimal(cs);
  173           }
  174           catch (NumberFormatException e) {
  175               String msg = "invalid long: " + cs;
  176               errors.add(XmlError.forMessage(msg));
  177               return DECIMAL__ZERO;
  178           }
  179       }
  180   
  181       private static final char[] CH_ZEROS = new char[] {'0', '0', '0', '0', '0', '0', '0', '0',
  182           '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'};
  183   
  184       public static String printDecimal(BigDecimal value)
  185       {
  186           // We can't simply use value.toString() here, because in JDK1.5 that returns an
  187           // exponent String and exponents are not allowed in XMLSchema decimal values
  188           // The following code comes from Apache Harmony
  189           String intStr = value.unscaledValue().toString();
  190           int scale = value.scale();
  191           if ((scale == 0) || ((value.longValue() == 0) && (scale < 0)))
  192               return intStr;
  193   
  194           int begin = (value.signum() < 0) ? 1 : 0;
  195           int delta = scale;
  196           // We take space for all digits, plus a possible decimal point, plus 'scale'
  197           StringBuffer result = new StringBuffer(intStr.length() + 1 + Math.abs(scale));
  198   
  199           if (begin == 1)
  200           {
  201               // If the number is negative, we insert a '-' character at front 
  202               result.append('-');
  203           }
  204           if (scale > 0)
  205           {
  206               delta -= (intStr.length() - begin);
  207               if (delta >= 0)
  208               {
  209                   result.append("0."); //$NON-NLS-1$
  210                   // To append zeros after the decimal point
  211                   for (; delta > CH_ZEROS.length; delta -= CH_ZEROS.length)
  212                       result.append(CH_ZEROS);
  213                   result.append(CH_ZEROS, 0, delta);
  214                   result.append(intStr.substring(begin));
  215               }
  216               else
  217               {
  218                   delta = begin - delta;
  219                   result.append(intStr.substring(begin, delta));
  220                   result.append('.');
  221                   result.append(intStr.substring(delta));
  222               }
  223           }
  224           else
  225           {// (scale <= 0)
  226               result.append(intStr.substring(begin));
  227               // To append trailing zeros
  228               for (; delta < -CH_ZEROS.length; delta += CH_ZEROS.length)
  229                   result.append(CH_ZEROS);
  230               result.append(CH_ZEROS, 0, -delta);
  231           }
  232           return result.toString();
  233       }
  234   
  235       // ======================== integer ========================
  236       public static BigInteger lexInteger(CharSequence cs)
  237           throws NumberFormatException
  238       {
  239           if (cs.length() > 1) {
  240               if (cs.charAt(0) == '+' && cs.charAt(1) == '-')
  241                   throw new NumberFormatException("Illegal char sequence '+-'");
  242           }
  243           final String v = cs.toString();
  244   
  245           //TODO: consider special casing zero and one to return static values
  246           //from BigInteger to avoid object creation.
  247           return new BigInteger(trimInitialPlus(v));
  248       }
  249   
  250       public static BigInteger lexInteger(CharSequence cs, Collection errors)
  251       {
  252           try {
  253               return lexInteger(cs);
  254           }
  255           catch (NumberFormatException e) {
  256               String msg = "invalid long: " + cs;
  257               errors.add(XmlError.forMessage(msg));
  258               return BigInteger.ZERO;
  259           }
  260       }
  261   
  262       public static String printInteger(BigInteger value)
  263       {
  264           return value.toString();
  265       }
  266   
  267       // ======================== long ========================
  268       public static long lexLong(CharSequence cs)
  269           throws NumberFormatException
  270       {
  271           final String v = cs.toString();
  272           return Long.parseLong(trimInitialPlus(v));
  273       }
  274   
  275       public static long lexLong(CharSequence cs, Collection errors)
  276       {
  277           try {
  278               return lexLong(cs);
  279           }
  280           catch (NumberFormatException e) {
  281               String msg = "invalid long: " + cs;
  282               errors.add(XmlError.forMessage(msg));
  283               return 0L;
  284           }
  285       }
  286   
  287       public static String printLong(long value)
  288       {
  289           return Long.toString(value);
  290       }
  291   
  292   
  293       // ======================== short ========================
  294       public static short lexShort(CharSequence cs)
  295           throws NumberFormatException
  296       {
  297           return parseShort(cs);
  298       }
  299   
  300       public static short lexShort(CharSequence cs, Collection errors)
  301       {
  302           try {
  303               return lexShort(cs);
  304           }
  305           catch (NumberFormatException e) {
  306               String msg = "invalid short: " + cs;
  307               errors.add(XmlError.forMessage(msg));
  308               return 0;
  309           }
  310       }
  311   
  312       public static String printShort(short value)
  313       {
  314           return Short.toString(value);
  315       }
  316   
  317   
  318       // ======================== int ========================
  319       public static int lexInt(CharSequence cs)
  320           throws NumberFormatException
  321       {
  322           return parseInt(cs);
  323       }
  324   
  325       public static int lexInt(CharSequence cs, Collection errors)
  326       {
  327           try {
  328               return lexInt(cs);
  329           }
  330           catch (NumberFormatException e) {
  331               String msg = "invalid int:" + cs;
  332               errors.add(XmlError.forMessage(msg));
  333               return 0;
  334           }
  335       }
  336   
  337       public static String printInt(int value)
  338       {
  339           return Integer.toString(value);
  340       }
  341   
  342   
  343       // ======================== byte ========================
  344       public static byte lexByte(CharSequence cs)
  345           throws NumberFormatException
  346       {
  347           return parseByte(cs);
  348       }
  349   
  350       public static byte lexByte(CharSequence cs, Collection errors)
  351       {
  352           try {
  353               return lexByte(cs);
  354           }
  355           catch (NumberFormatException e) {
  356               String msg = "invalid byte: " + cs;
  357               errors.add(XmlError.forMessage(msg));
  358               return 0;
  359           }
  360       }
  361   
  362       public static String printByte(byte value)
  363       {
  364           return Byte.toString(value);
  365       }
  366   
  367   
  368       // ======================== boolean ========================
  369       public static boolean lexBoolean(CharSequence v)
  370       {
  371           switch (v.length()) {
  372               case 1:  // "0" or "1"
  373                   final char c = v.charAt(0);
  374                   if ('0' == c) return false;
  375                   if ('1' == c) return true;
  376                   break;
  377               case 4:  //"true"
  378                   if ('t' == v.charAt(0) &&
  379                       'r' == v.charAt(1) &&
  380                       'u' == v.charAt(2) &&
  381                       'e' == v.charAt(3)) {
  382                       return true;
  383                   }
  384                   break;
  385               case 5:  //"false"
  386                   if ('f' == v.charAt(0) &&
  387                       'a' == v.charAt(1) &&
  388                       'l' == v.charAt(2) &&
  389                       's' == v.charAt(3) &&
  390                       'e' == v.charAt(4)) {
  391                       return false;
  392                   }
  393                   break;
  394           }
  395   
  396           //reaching here means an invalid boolean lexical
  397           String msg = "invalid boolean: " + v;
  398           throw new InvalidLexicalValueException(msg);
  399       }
  400   
  401       public static boolean lexBoolean(CharSequence value, Collection errors)
  402       {
  403           try {
  404               return lexBoolean(value);
  405           }
  406           catch (InvalidLexicalValueException e) {
  407               errors.add(XmlError.forMessage(e.getMessage()));
  408               return false;
  409           }
  410       }
  411   
  412       public static String printBoolean(boolean value)
  413       {
  414           return (value ? "true" : "false");
  415       }
  416   
  417   
  418       // ======================== string ========================
  419       public static String lexString(CharSequence cs, Collection errors)
  420       {
  421           final String v = cs.toString();
  422   
  423           return v;
  424       }
  425   
  426   
  427       public static String lexString(CharSequence lexical_value)
  428       {
  429           return lexical_value.toString();
  430       }
  431   
  432       public static String printString(String value)
  433       {
  434           return value;
  435       }
  436   
  437   
  438       // ======================== QName ========================
  439       public static QName lexQName(CharSequence charSeq, NamespaceContext nscontext)
  440       {
  441           String prefix, localname;
  442   
  443           int firstcolon;
  444           boolean hasFirstCollon = false;
  445           for (firstcolon = 0; firstcolon < charSeq.length(); firstcolon++)
  446               if (charSeq.charAt(firstcolon) == NAMESPACE_SEP) {
  447                   hasFirstCollon = true;
  448                   break;
  449               }
  450   
  451           if (hasFirstCollon) {
  452               prefix = charSeq.subSequence(0, firstcolon).toString();
  453               localname = charSeq.subSequence(firstcolon + 1, charSeq.length()).toString();
  454               if (firstcolon == 0) {
  455                   throw new InvalidLexicalValueException("invalid xsd:QName '" + charSeq.toString() + "'");
  456               }
  457           } else {
  458               prefix = EMPTY_PREFIX;
  459               localname = charSeq.toString();
  460           }
  461   
  462           String uri = nscontext.getNamespaceURI(prefix);
  463   
  464           if (uri == null) {
  465               if (prefix != null && prefix.length() > 0)
  466                   throw new InvalidLexicalValueException("Can't resolve prefix: " + prefix);
  467   
  468               uri = "";
  469           }
  470   
  471           return new QName(uri, localname);
  472       }
  473   
  474       public static QName lexQName(String xsd_qname, Collection errors,
  475                                    NamespaceContext nscontext)
  476       {
  477           try {
  478               return lexQName(xsd_qname, nscontext);
  479           }
  480           catch (InvalidLexicalValueException e) {
  481               errors.add(XmlError.forMessage(e.getMessage()));
  482               final int idx = xsd_qname.indexOf(NAMESPACE_SEP);
  483               return new QName(null, xsd_qname.substring(idx));
  484           }
  485       }
  486   
  487       public static String printQName(QName qname, NamespaceContext nsContext,
  488                                       Collection errors)
  489       {
  490           final String uri = qname.getNamespaceURI();
  491           assert uri != null; //qname is not allowed to have null uri values
  492           final String prefix;
  493           if (uri.length() > 0) {
  494               prefix = nsContext.getPrefix(uri);
  495               if (prefix == null) {
  496                   String msg = "NamespaceContext does not provide" +
  497                       " prefix for namespaceURI " + uri;
  498                   errors.add(XmlError.forMessage(msg));
  499               }
  500           } else {
  501               prefix = null;
  502           }
  503           return getQNameString(uri, qname.getLocalPart(), prefix);
  504   
  505       }
  506   
  507       public static String getQNameString(String uri,
  508                                           String localpart,
  509                                           String prefix)
  510       {
  511           if (prefix != null &&
  512               uri != null &&
  513               uri.length() > 0 &&
  514               prefix.length() > 0) {
  515               return (prefix + NAMESPACE_SEP + localpart);
  516           } else {
  517               return localpart;
  518           }
  519       }
  520   
  521       // ======================== GDate ========================
  522       public static GDate lexGDate(CharSequence charSeq)
  523       {
  524           return new GDate(charSeq);
  525       }
  526   
  527       public static GDate lexGDate(String xsd_gdate, Collection errors)
  528       {
  529           try {
  530               return lexGDate(xsd_gdate);
  531           }
  532           catch (IllegalArgumentException e) {
  533               errors.add(XmlError.forMessage(e.getMessage()));
  534               return new GDateBuilder().toGDate();
  535           }
  536       }
  537   
  538       public static String printGDate(GDate gdate, Collection errors)
  539       {
  540           return gdate.toString();
  541       }
  542   
  543   
  544       // ======================== dateTime ========================
  545       public static XmlCalendar lexDateTime(CharSequence v)
  546       {
  547           GDateSpecification value = getGDateValue(v, SchemaType.BTC_DATE_TIME);
  548           return value.getCalendar();
  549       }
  550   
  551   
  552       public static String printDateTime(Calendar c)
  553       {
  554           return printDateTime(c, SchemaType.BTC_DATE_TIME);
  555       }
  556   
  557       public static String printTime(Calendar c)
  558       {
  559           return printDateTime(c, SchemaType.BTC_TIME);
  560       }
  561   
  562       public static String printDate(Calendar c)
  563       {
  564           return printDateTime(c, SchemaType.BTC_DATE);
  565       }
  566   
  567       public static String printDate(Date d)
  568       {
  569           GDateSpecification value = getGDateValue(d, SchemaType.BTC_DATE);
  570           return value.toString();
  571       }
  572   
  573       public static String printDateTime(Calendar c, int type_code)
  574       {
  575           GDateSpecification value = getGDateValue(c, type_code);
  576           return value.toString();
  577       }
  578   
  579       public static String printDateTime(Date c)
  580       {
  581           GDateSpecification value = getGDateValue(c, SchemaType.BTC_DATE_TIME);
  582           return value.toString();
  583       }
  584   
  585   
  586       // ======================== hexBinary ========================
  587       public static CharSequence printHexBinary(byte[] val)
  588       {
  589           return HexBin.bytesToString(val);
  590       }
  591   
  592       public static byte[] lexHexBinary(CharSequence lexical_value)
  593       {
  594           byte[] buf = HexBin.decode(lexical_value.toString().getBytes());
  595           if (buf != null)
  596               return buf;
  597           else
  598               throw new InvalidLexicalValueException("invalid hexBinary value");
  599       }
  600   
  601   
  602       // ======================== base64binary ========================
  603       public static CharSequence printBase64Binary(byte[] val)
  604       {
  605           final byte[] bytes = Base64.encode(val);
  606           return new String(bytes);
  607       }
  608   
  609       public static byte[] lexBase64Binary(CharSequence lexical_value)
  610       {
  611           byte[] buf = Base64.decode(lexical_value.toString().getBytes());
  612           if (buf != null)
  613               return buf;
  614           else
  615               throw new InvalidLexicalValueException("invalid base64Binary value");
  616       }
  617   
  618   
  619       // date utils
  620       public static GDateSpecification getGDateValue(Date d,
  621                                                      int builtin_type_code)
  622       {
  623           GDateBuilder gDateBuilder = new GDateBuilder(d);
  624           gDateBuilder.setBuiltinTypeCode(builtin_type_code);
  625           GDate value = gDateBuilder.toGDate();
  626           return value;
  627       }
  628   
  629   
  630       public static GDateSpecification getGDateValue(Calendar c,
  631                                                      int builtin_type_code)
  632       {
  633           GDateBuilder gDateBuilder = new GDateBuilder(c);
  634           gDateBuilder.setBuiltinTypeCode(builtin_type_code);
  635           GDate value = gDateBuilder.toGDate();
  636           return value;
  637       }
  638   
  639       public static GDateSpecification getGDateValue(CharSequence v,
  640                                                      int builtin_type_code)
  641       {
  642           GDateBuilder gDateBuilder = new GDateBuilder(v);
  643           gDateBuilder.setBuiltinTypeCode(builtin_type_code);
  644           GDate value = gDateBuilder.toGDate();
  645           return value;
  646       }
  647   
  648       private static String trimInitialPlus(String xml)
  649       {
  650           if (xml.length() > 0 && xml.charAt(0) == '+') {
  651               return xml.substring(1);
  652           } else {
  653               return xml;
  654           }
  655       }
  656   
  657       private static String trimTrailingZeros(String xsd_decimal)
  658       {
  659           final int last_char_idx = xsd_decimal.length() - 1;
  660           if (xsd_decimal.charAt(last_char_idx) == '0')
  661           {
  662               final int last_point = xsd_decimal.lastIndexOf('.');
  663               if (last_point >= 0) {
  664                   //find last trailing zero
  665                   for (int idx = last_char_idx; idx > last_point; idx--) {
  666                       if (xsd_decimal.charAt(idx) != '0') {
  667                           return xsd_decimal.substring(0, idx + 1);
  668                       }
  669                   }
  670                   //reaching here means the string matched xxx.0*
  671                   return xsd_decimal.substring(0, last_point);
  672               }
  673           }
  674           return xsd_decimal;
  675       }
  676   
  677       private static int parseInt(CharSequence cs)
  678       {
  679           return parseIntXsdNumber(cs, Integer.MIN_VALUE, Integer.MAX_VALUE);
  680       }
  681   
  682       private static short parseShort(CharSequence cs)
  683       {
  684           return (short)parseIntXsdNumber(cs, Short.MIN_VALUE, Short.MAX_VALUE);
  685       }
  686   
  687       private static byte parseByte(CharSequence cs)
  688       {
  689           return (byte)parseIntXsdNumber(cs, Byte.MIN_VALUE, Byte.MAX_VALUE);
  690       }
  691   
  692       private static int parseIntXsdNumber(CharSequence ch, int min_value, int max_value)
  693       {
  694           // int parser on a CharSequence
  695           int length = ch.length();
  696           if (length < 1)
  697               throw new NumberFormatException("For input string: \"" + ch.toString() + "\"");
  698   
  699           int sign = 1;
  700           int result = 0;
  701           int start = 0;
  702           int limit;
  703           int limit2;
  704   
  705           char c = ch.charAt(0);
  706           if (c == '-') {
  707               start++;
  708               limit = (min_value / 10);
  709               limit2 = -(min_value % 10);
  710           } else if (c == '+') {
  711               start++;
  712               sign = -1;
  713               limit = -(max_value / 10);
  714               limit2 = (max_value % 10);
  715           } else {
  716               sign = -1;
  717               limit = -(max_value / 10);
  718               limit2 = (max_value % 10);
  719           }
  720   
  721           for (int i = 0; i < length - start; i++) {
  722               c = ch.charAt(i + start);
  723               int v = Character.digit(c, 10);
  724   
  725               if (v < 0)
  726                   throw new NumberFormatException("For input string: \"" + ch.toString() + "\"");
  727   
  728               if (result < limit || (result==limit && v > limit2))
  729                   throw new NumberFormatException("For input string: \"" + ch.toString() + "\"");
  730   
  731               result = result * 10 - v;
  732           }
  733   
  734           return sign * result;
  735       }
  736   
  737       // ======================== anyURI ========================
  738       public static CharSequence printAnyURI(CharSequence val)
  739       {
  740           return val;
  741       }
  742   
  743       /**
  744        * Checkes the regular expression of URI, defined by RFC2369 http://www.ietf.org/rfc/rfc2396.txt Appendix B.
  745        * Note: The whitespace normalization rule collapse must be applied priot to calling this method.
  746        * @param lexical_value the lexical value
  747        * @return same input value if input value is in the lexical space
  748        * @throws InvalidLexicalValueException
  749        */
  750       public static CharSequence lexAnyURI(CharSequence lexical_value)
  751       {
  752           /*  // Reg exp from RFC2396, but it's too forgiving for XQTS
  753           Pattern p = Pattern.compile("^([^:/?#]+:)?(//[^/?#]*)?([^?#]*)(\\?[^#]*)?(#.*)?");
  754           Matcher m = p.matcher(lexical_value);
  755           if ( !m.matches() )
  756               throw new InvalidLexicalValueException("invalid anyURI value");
  757           else
  758           {
  759               for ( int i = 0; i<= m.groupCount(); i++ )
  760               {
  761                   System.out.print("  " + i + ": " + m.group(i));
  762               }
  763               System.out.println("");
  764               return lexical_value;
  765           } */
  766   
  767           // Per XMLSchema spec allow spaces inside URIs
  768           StringBuffer s = new StringBuffer(lexical_value.toString());
  769           for (int ic = 0; ic<URI_CHARS_TO_BE_REPLACED.length; ic++)
  770           {
  771               int i = 0;
  772               while ((i = s.indexOf(URI_CHARS_TO_BE_REPLACED[ic], i)) >= 0)
  773               {
  774                   s.replace(i, i + 1, URI_CHARS_REPLACED_WITH[ic]);
  775                   i += 3;
  776               }
  777           }
  778   
  779           try
  780           {
  781               URI.create(s.toString());
  782           }
  783           catch (IllegalArgumentException e)
  784           {
  785               throw new InvalidLexicalValueException("invalid anyURI value: " + lexical_value, e);
  786           }
  787   
  788           return lexical_value;
  789       }
  790   }

Home » xmlbeans-2.5.0-src » org.apache.xmlbeans.impl » util » [javadoc | source]