Search in sources :

Example 1 with DontLoadProxy

use of logisticspipes.proxy.DontLoadProxy in project LogisticsPipes by RS485.

the class LogisticsWrapperHandler method getWrappedProxy.

@SuppressWarnings("unchecked")
public static <T> T getWrappedProxy(String modId, Class<T> interfaze, Class<? extends T> proxyClazz, T dummyProxy, Class<?>... wrapperInterfaces) throws SecurityException, IllegalArgumentException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException {
    String proxyName = interfaze.getSimpleName().substring(1);
    if (!proxyName.endsWith("Proxy")) {
        throw new RuntimeException("UnuportedProxyName: " + proxyName);
    }
    proxyName = proxyName.substring(0, proxyName.length() - 5);
    String className = "logisticspipes/asm/wrapper/generated/" + proxyName + "ProxyWrapper";
    boolean ignoreModLoaded = false;
    if (modId.startsWith("!")) {
        ignoreModLoaded = true;
        modId = modId.substring(1);
    }
    List<Class<?>> wrapperInterfacesList = Arrays.asList(wrapperInterfaces);
    Class<?> clazz;
    synchronized (lookupMap) {
        clazz = LogisticsWrapperHandler.lookupMap.get(className);
        if (clazz == null) {
            String fieldName = interfaze.getName().replace('.', '/');
            // String classFile = interfaze.getSimpleName().substring(1) + "Wrapper.java";
            ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
            cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, className, null, "logisticspipes/asm/wrapper/AbstractWrapper", new String[] { fieldName });
            cw.visitSource(".LP|ASM.dynamic", null);
            {
                FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE, "proxy", "L" + fieldName + ";", null, null);
                fv.visitEnd();
            }
            {
                FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL, "dummyProxy", "L" + fieldName + ";", null, null);
                fv.visitEnd();
            }
            {
                MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "(L" + fieldName + ";L" + fieldName + ";)V", null, null);
                mv.visitCode();
                Label l0 = new Label();
                mv.visitLabel(l0);
                mv.visitLineNumber(11, l0);
                mv.visitVarInsn(Opcodes.ALOAD, 0);
                mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "logisticspipes/asm/wrapper/AbstractWrapper", "<init>", "()V");
                Label l1 = new Label();
                mv.visitLabel(l1);
                mv.visitLineNumber(12, l1);
                mv.visitVarInsn(Opcodes.ALOAD, 0);
                mv.visitVarInsn(Opcodes.ALOAD, 1);
                mv.visitFieldInsn(Opcodes.PUTFIELD, className, "dummyProxy", "L" + fieldName + ";");
                Label l2 = new Label();
                mv.visitLabel(l2);
                mv.visitLineNumber(13, l2);
                mv.visitVarInsn(Opcodes.ALOAD, 0);
                mv.visitVarInsn(Opcodes.ALOAD, 2);
                mv.visitFieldInsn(Opcodes.PUTFIELD, className, "proxy", "L" + fieldName + ";");
                Label l3 = new Label();
                mv.visitLabel(l3);
                mv.visitLineNumber(14, l3);
                mv.visitInsn(Opcodes.RETURN);
                Label l4 = new Label();
                mv.visitLabel(l4);
                mv.visitLocalVariable("this", "L" + className + ";", null, l0, l4, 0);
                mv.visitLocalVariable("dProxy", "L" + fieldName + ";", null, l0, l4, 1);
                mv.visitLocalVariable("iProxy", "L" + fieldName + ";", null, l0, l4, 2);
                mv.visitMaxs(2, 3);
                mv.visitEnd();
            }
            int lineAddition = 100;
            for (Method method : interfaze.getMethods()) {
                LogisticsWrapperHandler.addProxyMethod(cw, method, fieldName, className, lineAddition, !wrapperInterfacesList.contains(method.getReturnType()));
                lineAddition += 10;
            }
            LogisticsWrapperHandler.addGetName(cw, className, proxyName);
            LogisticsWrapperHandler.addGetTypeName(cw, className, "Proxy");
            cw.visitEnd();
            String lookfor = className.replace('/', '.');
            byte[] bytes = cw.toByteArray();
            if (LogisticsPipes.isDEBUG()) {
                if (LogisticsWrapperHandler.DUMP) {
                    LogisticsWrapperHandler.saveGeneratedClass(bytes, lookfor, "LP_WRAPPER_CLASSES");
                }
                ClassReader cr = new ClassReader(bytes);
                org.objectweb.asm.util.CheckClassAdapter.verify(cr, Launch.classLoader, false, new PrintWriter(System.err));
            }
            try {
                clazz = LogisticsWrapperHandler.loadClass(bytes, lookfor);
            } catch (LinkageError e) {
                try {
                    if (e.getMessage().contains("attempted") && e.getMessage().contains("duplicate class definition")) {
                        Class<?> prev = Class.forName(className);
                        System.err.println(e.getMessage());
                        System.err.printf("Already loaded: %s%n", prev);
                        String resourcePath = className.replace('.', '/').concat(".class");
                        URL classResource = Launch.classLoader.findResource(resourcePath);
                        if (classResource != null) {
                            String path = classResource.getPath();
                            System.err.println("Class source: " + path);
                        } else {
                            System.err.println("Class source: Null");
                        }
                    }
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
                throw e;
            }
            LogisticsWrapperHandler.lookupMap.put(className, clazz);
        }
    }
    T proxy = null;
    Throwable e = null;
    if ((ModStatusHelper.areModsLoaded(modId) || ignoreModLoaded) && proxyClazz != null) {
        try {
            proxy = proxyClazz.newInstance();
        } catch (Exception e1) {
            if (e1 instanceof VersionNotSupportedException) {
                throw (VersionNotSupportedException) e1;
            }
            if (!(e1 instanceof DontLoadProxy)) {
                e1.printStackTrace();
                e = e1;
            }
        } catch (NoClassDefFoundError e1) {
            if (!ignoreModLoaded) {
                e1.printStackTrace();
                e = e1;
            }
        }
    }
    T instance = (T) clazz.getConstructor(new Class<?>[] { interfaze, interfaze }).newInstance(dummyProxy, proxy);
    if (proxy != null) {
        LogisticsPipes.log.info("Loaded " + proxyName + "Proxy");
    } else {
        LogisticsPipes.log.info("Loaded " + proxyName + " DummyProxy");
        if (e != null) {
            ((AbstractWrapper) instance).setState(WrapperState.Exception);
            ((AbstractWrapper) instance).setReason(e);
        } else {
            ((AbstractWrapper) instance).setState(WrapperState.ModMissing);
        }
    }
    ((AbstractWrapper) instance).setModId(modId);
    ((AbstractWrapper) instance).setWrapperInterfaces(Collections.unmodifiableList(wrapperInterfacesList));
    LogisticsWrapperHandler.wrapperController.add((AbstractWrapper) instance);
    return instance;
}
Also used : DontLoadProxy(logisticspipes.proxy.DontLoadProxy) Label(org.objectweb.asm.Label) Method(java.lang.reflect.Method) FieldVisitor(org.objectweb.asm.FieldVisitor) VersionNotSupportedException(logisticspipes.proxy.VersionNotSupportedException) ClassWriter(org.objectweb.asm.ClassWriter) URL(java.net.URL) VersionNotSupportedException(logisticspipes.proxy.VersionNotSupportedException) IOException(java.io.IOException) InvocationTargetException(java.lang.reflect.InvocationTargetException) MethodVisitor(org.objectweb.asm.MethodVisitor) ClassReader(org.objectweb.asm.ClassReader) PrintWriter(java.io.PrintWriter)

Aggregations

IOException (java.io.IOException)1 PrintWriter (java.io.PrintWriter)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 Method (java.lang.reflect.Method)1 URL (java.net.URL)1 DontLoadProxy (logisticspipes.proxy.DontLoadProxy)1 VersionNotSupportedException (logisticspipes.proxy.VersionNotSupportedException)1 ClassReader (org.objectweb.asm.ClassReader)1 ClassWriter (org.objectweb.asm.ClassWriter)1 FieldVisitor (org.objectweb.asm.FieldVisitor)1 Label (org.objectweb.asm.Label)1 MethodVisitor (org.objectweb.asm.MethodVisitor)1