UnderscoreNameLinkerExporter.java revision 1805:7caf1f762f1d
1/* 2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * - Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * - Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * - Neither the name of Oracle nor the names of its 16 * contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32import java.util.ArrayList; 33import java.util.List; 34import java.util.regex.Matcher; 35import java.util.regex.Pattern; 36import jdk.dynalink.CallSiteDescriptor; 37import jdk.dynalink.NamedOperation; 38import jdk.dynalink.NamespaceOperation; 39import jdk.dynalink.Operation; 40import jdk.dynalink.StandardNamespace; 41import jdk.dynalink.StandardOperation; 42import jdk.dynalink.linker.GuardedInvocation; 43import jdk.dynalink.linker.GuardingDynamicLinker; 44import jdk.dynalink.linker.GuardingDynamicLinkerExporter; 45import jdk.dynalink.linker.LinkRequest; 46import jdk.dynalink.linker.LinkerServices; 47import jdk.dynalink.linker.support.SimpleLinkRequest; 48 49/** 50 * This is a dynalink pluggable linker (see http://openjdk.java.net/jeps/276). 51 * This linker translater underscore_separated method names to CamelCase names 52 * used in Java APIs. 53 */ 54public final class UnderscoreNameLinkerExporter extends GuardingDynamicLinkerExporter { 55 static { 56 System.out.println("pluggable dynalink underscore name linker loaded"); 57 } 58 59 private static final Pattern UNDERSCORE_NAME = Pattern.compile("_(.)"); 60 61 // translate underscore_separated name as a CamelCase name 62 private static String translateToCamelCase(final String name) { 63 final Matcher m = UNDERSCORE_NAME.matcher(name); 64 final StringBuilder buf = new StringBuilder(); 65 while (m.find()) { 66 m.appendReplacement(buf, m.group(1).toUpperCase()); 67 } 68 m.appendTail(buf); 69 return buf.toString(); 70 } 71 72 @Override 73 public List<GuardingDynamicLinker> get() { 74 final ArrayList<GuardingDynamicLinker> linkers = new ArrayList<>(); 75 linkers.add(new GuardingDynamicLinker() { 76 @Override 77 public GuardedInvocation getGuardedInvocation(final LinkRequest request, 78 final LinkerServices linkerServices) throws Exception { 79 final CallSiteDescriptor desc = request.getCallSiteDescriptor(); 80 final Operation op = desc.getOperation(); 81 final Object name = NamedOperation.getName(op); 82 final Operation namespaceOp = NamedOperation.getBaseOperation(op); 83 // is this a named GET_METHOD? 84 final boolean isGetMethod = 85 NamespaceOperation.getBaseOperation(namespaceOp) == StandardOperation.GET 86 && StandardNamespace.findFirst(namespaceOp) == StandardNamespace.METHOD; 87 if (isGetMethod && name instanceof String) { 88 final String str = (String)name; 89 if (str.indexOf('_') == -1) { 90 return null; 91 } 92 93 final String nameStr = translateToCamelCase(str); 94 // create a new call descriptor to use translated name 95 final CallSiteDescriptor newDesc = desc.changeOperation(((NamedOperation)op).changeName(nameStr)); 96 // create a new Link request to link the call site with translated name 97 final LinkRequest newRequest = request.replaceArguments(newDesc, request.getArguments()); 98 // return guarded invocation linking the translated request 99 return linkerServices.getGuardedInvocation(newRequest); 100 } 101 102 return null; 103 } 104 }); 105 return linkers; 106 } 107} 108