src/share/jaxws_classes/com/sun/xml/internal/bind/api/impl/NameConverter.java

Tue, 09 Apr 2013 14:51:13 +0100

author
alanb
date
Tue, 09 Apr 2013 14:51:13 +0100
changeset 368
0989ad8c0860
parent 286
f50545b5e2f1
child 637
9c07ef4934dd
permissions
-rw-r--r--

8010393: Update JAX-WS RI to 2.2.9-b12941
Reviewed-by: alanb, erikj
Contributed-by: miroslav.kos@oracle.com, martin.grebac@oracle.com

     1 /*
     2  * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    26 package com.sun.xml.internal.bind.api.impl;
    28 import javax.lang.model.SourceVersion;
    29 import java.util.ArrayList;
    30 import java.util.List;
    31 import java.util.StringTokenizer;
    33 /**
    34  * Converts aribitrary strings into Java identifiers.
    35  *
    36  * @author
    37  *    <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a>
    38  */
    39 public interface NameConverter
    40 {
    41     /**
    42      * converts a string into an identifier suitable for classes.
    43      *
    44      * In general, this operation should generate "NamesLikeThis".
    45      */
    46     String toClassName( String token );
    48     /**
    49      * converts a string into an identifier suitable for interfaces.
    50      *
    51      * In general, this operation should generate "NamesLikeThis".
    52      * But for example, it can prepend every interface with 'I'.
    53      */
    54     String toInterfaceName( String token );
    56     /**
    57      * converts a string into an identifier suitable for properties.
    58      *
    59      * In general, this operation should generate "NamesLikeThis",
    60      * which will be used with known prefixes like "get" or "set".
    61      */
    62     String toPropertyName( String token );
    64     /**
    65      * converts a string into an identifier suitable for constants.
    66      *
    67      * In the standard Java naming convention, this operation should
    68      * generate "NAMES_LIKE_THIS".
    69      */
    70     String toConstantName( String token );
    72     /**
    73      * Converts a string into an identifier suitable for variables.
    74      *
    75      * In general it should generate "namesLikeThis".
    76      */
    77     String toVariableName( String token );
    79     /**
    80      * Converts a namespace URI into a package name.
    81      * This method should expect strings like
    82      * "http://foo.bar.zot/org", "urn:abc:def:ghi" "", or even "###"
    83      * (basically anything) and expected to return a package name,
    84      * liks "org.acme.foo".
    85      *
    86      */
    87     String toPackageName( String namespaceUri );
    89     /**
    90      * The name converter implemented by Code Model.
    91      *
    92      * This is the standard name conversion for JAXB.
    93      */
    94     public static final NameConverter standard = new Standard();
    96     static class Standard extends NameUtil implements NameConverter {
    97         public String toClassName(String s) {
    98             return toMixedCaseName(toWordList(s), true);
    99         }
   100         public String toVariableName(String s) {
   101             return toMixedCaseName(toWordList(s), false);
   102         }
   103         public String toInterfaceName( String token ) {
   104             return toClassName(token);
   105         }
   106         public String toPropertyName(String s) {
   107             String prop = toClassName(s);
   108             // property name "Class" with collide with Object.getClass,
   109             // so escape this.
   110             if(prop.equals("Class"))
   111                 prop = "Clazz";
   112             return prop;
   113         }
   114         public String toConstantName( String token ) {
   115             return super.toConstantName(token);
   116         }
   117         /**
   118          * Computes a Java package name from a namespace URI,
   119          * as specified in the spec.
   120          *
   121          * @return
   122          *      null if it fails to derive a package name.
   123          */
   124         public String toPackageName( String nsUri ) {
   125             // remove scheme and :, if present
   126             // spec only requires us to remove 'http' and 'urn'...
   127             int idx = nsUri.indexOf(':');
   128             String scheme = "";
   129             if(idx>=0) {
   130                 scheme = nsUri.substring(0,idx);
   131                 if( scheme.equalsIgnoreCase("http") || scheme.equalsIgnoreCase("urn") )
   132                     nsUri = nsUri.substring(idx+1);
   133             }
   135             // tokenize string
   136             ArrayList<String> tokens = tokenize( nsUri, "/: " );
   137             if( tokens.size() == 0 ) {
   138                 return null;
   139             }
   141             // remove trailing file type, if necessary
   142             if( tokens.size() > 1 ) {
   143                 // for uri's like "www.foo.com" and "foo.com", there is no trailing
   144                 // file, so there's no need to look at the last '.' and substring
   145                 // otherwise, we loose the "com" (which would be wrong)
   146                 String lastToken = tokens.get( tokens.size()-1 );
   147                 idx = lastToken.lastIndexOf( '.' );
   148                 if( idx > 0 ) {
   149                     lastToken = lastToken.substring( 0, idx );
   150                     tokens.set( tokens.size()-1, lastToken );
   151                 }
   152             }
   154             // tokenize domain name and reverse.  Also remove :port if it exists
   155             String domain = tokens.get( 0 );
   156             idx = domain.indexOf(':');
   157             if( idx >= 0) domain = domain.substring(0, idx);
   158             ArrayList<String> r = reverse( tokenize( domain, scheme.equals("urn")?".-":"." ) );
   159             if( r.get( r.size()-1 ).equalsIgnoreCase( "www" ) ) {
   160                 // remove leading www
   161                 r.remove( r.size()-1 );
   162             }
   164             // replace the domain name with tokenized items
   165             tokens.addAll( 1, r );
   166             tokens.remove( 0 );
   168             // iterate through the tokens and apply xml->java name algorithm
   169             for( int i = 0; i < tokens.size(); i++ ) {
   171                 // get the token and remove illegal chars
   172                 String token = tokens.get( i );
   173                 token = removeIllegalIdentifierChars( token );
   175                 // this will check for reserved keywords
   176                 if (SourceVersion.isKeyword(token.toLowerCase())) {
   177                     token = '_' + token;
   178                 }
   180                 tokens.set( i, token.toLowerCase() );
   181             }
   183             // concat all the pieces and return it
   184             return combine( tokens, '.' );
   185         }
   188         private static String removeIllegalIdentifierChars(String token) {
   189             StringBuilder newToken = new StringBuilder(token.length() + 1); // max expected length
   190             for( int i = 0; i < token.length(); i++ ) {
   191                 char c = token.charAt( i );
   192                 if (i == 0 && !Character.isJavaIdentifierStart(c)) { // c can't be used as FIRST char
   193                     newToken.append('_');
   194                 }
   195                 if (!Character.isJavaIdentifierPart(c)) { // c can't be used
   196                     newToken.append('_');
   197                 } else {
   198                     newToken.append(c); // c is valid
   199                 }
   200             }
   201             return newToken.toString();
   202         }
   205         private static ArrayList<String> tokenize( String str, String sep ) {
   206             StringTokenizer tokens = new StringTokenizer(str,sep);
   207             ArrayList<String> r = new ArrayList<String>();
   209             while(tokens.hasMoreTokens())
   210                 r.add( tokens.nextToken() );
   212             return r;
   213         }
   215         private static <T> ArrayList<T> reverse( List<T> a ) {
   216             ArrayList<T> r = new ArrayList<T>();
   218             for( int i=a.size()-1; i>=0; i-- )
   219                 r.add( a.get(i) );
   221             return r;
   222         }
   224         private static String combine( List r, char sep ) {
   225             StringBuilder buf = new StringBuilder(r.get(0).toString());
   227             for( int i=1; i<r.size(); i++ ) {
   228                 buf.append(sep);
   229                 buf.append(r.get(i));
   230             }
   232             return buf.toString();
   233         }
   234     }
   236     /**
   237      * JAX-PRC compatible name converter implementation.
   238      *
   239      * The only difference is that we treat '_' as a valid character
   240      * and not as a word separator.
   241      */
   242     public static final NameConverter jaxrpcCompatible = new Standard() {
   243         protected boolean isPunct(char c) {
   244             return (c == '.' || c == '-' || c == ';' /*|| c == '_'*/ || c == '\u00b7'
   245                     || c == '\u0387' || c == '\u06dd' || c == '\u06de');
   246         }
   247         protected boolean isLetter(char c) {
   248             return super.isLetter(c) || c=='_';
   249         }
   251         protected int classify(char c0) {
   252             if(c0=='_') return NameUtil.OTHER_LETTER;
   253             return super.classify(c0);
   254         }
   255     };
   257     /**
   258      * Smarter converter used for RELAX NG support.
   259      */
   260     public static final NameConverter smart = new Standard() {
   261         public String toConstantName( String token ) {
   262             String name = super.toConstantName(token);
   263             if(!SourceVersion.isKeyword(name))
   264                 return name;
   265             else
   266                 return '_'+name;
   267         }
   268     };
   269 }

mercurial