/** * Facilitates the creation of simple "function objects" that implement one or more interfaces by * delegation to a provided {@link MethodHandle}, after appropriate type adaptation and partial * evaluation of arguments. Typically used as a <em>bootstrap method</em> for {@code * invokedynamic} call sites, to support the <em>lambda expression</em> and <em>method reference * expression</em> features of the Java Programming Language. * * <p>This is the general, more flexible metafactory; a streamlined version is provided by {@link * #altMetafactory(MethodHandles.Lookup, String, MethodType, Object...)}. A general description of * the behavior of this method is provided {@link LambdaMetafactory above}. * * <p>The argument list for this method includes three fixed parameters, corresponding to the * parameters automatically stacked by the VM for the bootstrap method in an {@code invokedynamic} * invocation, and an {@code Object[]} parameter that contains additional parameters. The declared * argument list for this method is: * * <pre>{@code * CallSite altMetafactory(MethodHandles.Lookup caller, * String invokedName, * MethodType invokedType, * Object... args) * }</pre> * * <p>but it behaves as if the argument list is as follows: * * <pre>{@code * CallSite altMetafactory(MethodHandles.Lookup caller, * String invokedName, * MethodType invokedType, * MethodType samMethodType, * MethodHandle implMethod, * MethodType instantiatedMethodType, * int flags, * int markerInterfaceCount, // IF flags has MARKERS set * Class... markerInterfaces, // IF flags has MARKERS set * int bridgeCount, // IF flags has BRIDGES set * MethodType... bridges // IF flags has BRIDGES set * ) * }</pre> * * <p>Arguments that appear in the argument list for {@link #metafactory(MethodHandles.Lookup, * String, MethodType, MethodType, MethodHandle, MethodType)} have the same specification as in * that method. The additional arguments are interpreted as follows: * * <ul> * <li>{@code flags} indicates additional options; this is a bitwise OR of desired flags. * Defined flags are {@link #FLAG_BRIDGES}, {@link #FLAG_MARKERS}, and {@link * #FLAG_SERIALIZABLE}. * <li>{@code markerInterfaceCount} is the number of additional interfaces the function object * should implement, and is present if and only if the {@code FLAG_MARKERS} flag is set. * <li>{@code markerInterfaces} is a variable-length list of additional interfaces to implement, * whose length equals {@code markerInterfaceCount}, and is present if and only if the * {@code FLAG_MARKERS} flag is set. * <li>{@code bridgeCount} is the number of additional method signatures the function object * should implement, and is present if and only if the {@code FLAG_BRIDGES} flag is set. * <li>{@code bridges} is a variable-length list of additional methods signatures to implement, * whose length equals {@code bridgeCount}, and is present if and only if the {@code * FLAG_BRIDGES} flag is set. * </ul> * * <p>Each class named by {@code markerInterfaces} is subject to the same restrictions as {@code * Rd}, the return type of {@code invokedType}, as described {@link LambdaMetafactory above}. Each * {@code MethodType} named by {@code bridges} is subject to the same restrictions as {@code * samMethodType}, as described {@link LambdaMetafactory above}. * * <p>When FLAG_SERIALIZABLE is set in {@code flags}, the function objects will implement {@code * Serializable}, and will have a {@code writeReplace} method that returns an appropriate {@link * SerializedLambda}. The {@code caller} class must have an appropriate {@code * $deserializeLambda$} method, as described in {@link SerializedLambda}. * * <p>When the target of the {@code CallSite} returned from this method is invoked, the resulting * function objects are instances of a class with the following properties: * * <ul> * <li>The class implements the interface named by the return type of {@code invokedType} and * any interfaces named by {@code markerInterfaces} * <li>The class declares methods with the name given by {@code invokedName}, and the signature * given by {@code samMethodType} and additional signatures given by {@code bridges} * <li>The class may override methods from {@code Object}, and may implement methods related to * serialization. * </ul> * * @param caller Represents a lookup context with the accessibility privileges of the caller. When * used with {@code invokedynamic}, this is stacked automatically by the VM. * @param invokedName The name of the method to implement. When used with {@code invokedynamic}, * this is provided by the {@code NameAndType} of the {@code InvokeDynamic} structure and is * stacked automatically by the VM. * @param invokedType The expected signature of the {@code CallSite}. The parameter types * represent the types of capture variables; the return type is the interface to implement. * When used with {@code invokedynamic}, this is provided by the {@code NameAndType} of the * {@code InvokeDynamic} structure and is stacked automatically by the VM. In the event that * the implementation method is an instance method and this signature has any parameters, the * first parameter in the invocation signature must correspond to the receiver. * @param args An {@code Object[]} array containing the required arguments {@code samMethodType}, * {@code implMethod}, {@code instantiatedMethodType}, {@code flags}, and any optional * arguments, as described {@link #altMetafactory(MethodHandles.Lookup, String, MethodType, * Object...)} above} * @return a CallSite whose target can be used to perform capture, generating instances of the * interface named by {@code invokedType} * @throws LambdaConversionException If any of the linkage invariants described {@link * LambdaMetafactory above} are violated */ public static CallSite altMetafactory( MethodHandles.Lookup caller, String invokedName, MethodType invokedType, Object... args) throws LambdaConversionException { MethodType samMethodType = (MethodType) args[0]; MethodHandle implMethod = (MethodHandle) args[1]; MethodType instantiatedMethodType = (MethodType) args[2]; int flags = (Integer) args[3]; Class<?>[] markerInterfaces; MethodType[] bridges; int argIndex = 4; if ((flags & FLAG_MARKERS) != 0) { int markerCount = (Integer) args[argIndex++]; markerInterfaces = new Class<?>[markerCount]; System.arraycopy(args, argIndex, markerInterfaces, 0, markerCount); argIndex += markerCount; } else markerInterfaces = EMPTY_CLASS_ARRAY; if ((flags & FLAG_BRIDGES) != 0) { int bridgeCount = (Integer) args[argIndex++]; bridges = new MethodType[bridgeCount]; System.arraycopy(args, argIndex, bridges, 0, bridgeCount); argIndex += bridgeCount; } else bridges = EMPTY_MT_ARRAY; boolean isSerializable = ((flags & FLAG_SERIALIZABLE) != 0); if (isSerializable) { boolean foundSerializableSupertype = Serializable.class.isAssignableFrom(invokedType.returnType()); for (Class<?> c : markerInterfaces) foundSerializableSupertype |= Serializable.class.isAssignableFrom(c); if (!foundSerializableSupertype) { markerInterfaces = Arrays.copyOf(markerInterfaces, markerInterfaces.length + 1); markerInterfaces[markerInterfaces.length - 1] = Serializable.class; } } AbstractValidatingLambdaMetafactory mf = new InnerClassLambdaMetafactory( caller, invokedType, invokedName, samMethodType, implMethod, instantiatedMethodType, isSerializable, markerInterfaces, bridges); mf.validateMetafactoryArgs(); return mf.buildCallSite(); }
private static String postData( MethodType method, String openfireUrl, Map<String, String> params) { try { StringBuilder data = new StringBuilder(); for (String s : params.keySet()) { String tmp = URLEncoder.encode(s, "UTF-8") + "=" + URLEncoder.encode(params.get(s), "UTF-8") + "&"; data.append(tmp); } // ADD METHOD String methodStr = URLEncoder.encode("type", "UTF-8") + "=" + URLEncoder.encode(method.toString().toLowerCase(), "UTF-8"); data.append(methodStr); // Send data URL url = new URL(openfireUrl); URLConnection conn = url.openConnection(); conn.setDoOutput(true); OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream()); wr.write(data.toString()); wr.flush(); // Get the response BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream())); StringBuilder sb = new StringBuilder(); String line; while ((line = rd.readLine()) != null) { sb.append(line); } wr.close(); rd.close(); // RESPONSE CODE return sb.toString(); } catch (Exception e) { e.printStackTrace(); } return ""; }
@Override public MethodTypeWrapper GetMethod(String method) throws TypingRuleException { MethodTypeWrapper resultMethod; if (!(fatherScope instanceof ClassScope)) { throw new Error("Internal error, method scope cann't be nested not in class scope"); } ClassScope classScope = (ClassScope) fatherScope; // if (classScope.getStaticMethodScopes().containsKey(method)) // { // return classScope.getStaticMethodScopes().get(method); // } resultMethod = classScope.getStaticMethod(method); if (resultMethod != null) return resultMethod; resultMethod = classScope.getVirtualMethod(method); if (resultMethod != null) { if (methodType.equals(MethodType.Static)) { throw new TypingRuleException( "Calling a local virtual method from inside a static method is not allowed", -1); } return resultMethod; } return fatherScope.GetMethod(method); }
@Override public Type GetVariable(String name) { // search parameters Type resultType = parameters.get(name); // search local vars if (resultType == null) { resultType = super.GetVariable(name); } if (resultType == null) { // search fields Scope currentScope = fatherScope; while (!(currentScope instanceof ClassScope)) currentScope = fatherScope; ClassScope classScope = (ClassScope) currentScope; resultType = classScope.getField(name); if (resultType != null && methodType.equals(MethodType.Static)) { throw new TypingRuleException("Use of field inside a static method is not allowed", -1); } // while (currentScope instanceof ClassScope) { // ClassScope classScope = (ClassScope) currentScope; // if (classScope.getFields().containsKey(name)) { // if (methodType.equals(MethodType.Static)) { // throw new TypingRuleException( // "Use of field inside a static method is not allowed", // -1); // } // if (methodType.equals(MethodType.Virtual)) { // resultType = classScope.getFields().get(name); // } // } // currentScope = currentScope.fatherScope; } return resultType; }
@Override public int hashCode() { int result = invocationType != null ? invocationType.hashCode() : 0; result = 31 * result + (methodType != null ? methodType.hashCode() : 0); return result; }