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

Thu, 31 Aug 2017 15:18:52 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:18:52 +0800
changeset 637
9c07ef4934dd
parent 368
0989ad8c0860
parent 0
373ffda63c9a
permissions
-rw-r--r--

merge

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

mercurial