Search in sources :

Example 1 with BaseWrapper

use of php.runtime.lang.BaseWrapper in project jphp by jphp-compiler.

the class MemoryOperation method get.

@SuppressWarnings("unchecked")
public static MemoryOperation get(final Class<?> type, Type genericTypes, boolean includeParents) {
    MemoryOperation operation = null;
    if (genericTypes instanceof ParameterizedType) {
        operation = genericOperations.get(new ParametrizedClass(type, ((ParameterizedType) genericTypes).getActualTypeArguments()));
    }
    if (operation == null) {
        operation = operations.get(type);
        if (operation == null) {
            if (type.isArray()) {
                MemoryOperation arrayMemoryOperation = new ArrayMemoryOperation(type);
                register(arrayMemoryOperation);
                return arrayMemoryOperation;
            }
            if (Enum.class.isAssignableFrom(type)) {
                return new MemoryOperation() {

                    @Override
                    public Class<?>[] getOperationClasses() {
                        return new Class<?>[] { Enum.class };
                    }

                    @Override
                    @SuppressWarnings("unchecked")
                    public Object convert(Environment env, TraceInfo trace, Memory arg) throws Throwable {
                        return arg.isNull() ? null : Enum.valueOf((Class<? extends Enum>) type, arg.toString());
                    }

                    @Override
                    public Memory unconvert(Environment env, TraceInfo trace, Object arg) throws Throwable {
                        return arg == null ? Memory.NULL : StringMemory.valueOf(((Enum) arg).name());
                    }

                    @Override
                    public void applyTypeHinting(ParameterEntity parameter) {
                        parameter.setTypeEnum((Class<? extends Enum>) type);
                    }
                };
            }
            final Class<? extends BaseWrapper> wrapperClass = wrappers.get(type);
            if (wrapperClass != null) {
                Constructor<BaseWrapper> constructor;
                try {
                    constructor = (Constructor<BaseWrapper>) wrapperClass.getConstructor(Environment.class, type);
                } catch (NoSuchMethodException e) {
                    try {
                        constructor = (Constructor<BaseWrapper>) wrapperClass.getConstructor(Environment.class, Object.class);
                    } catch (NoSuchMethodException e1) {
                        throw new CriticalException(e);
                    }
                }
                final Constructor<BaseWrapper> finalConstructor = constructor;
                return new MemoryOperation() {

                    @Override
                    public Class<?>[] getOperationClasses() {
                        return new Class<?>[0];
                    }

                    @Override
                    public Object convert(Environment env, TraceInfo trace, Memory arg) throws Throwable {
                        if (arg.isNull()) {
                            return null;
                        }
                        return arg.toObject(BaseWrapper.class).getWrappedObject();
                    }

                    @Override
                    public Memory unconvert(Environment env, TraceInfo trace, Object arg) throws Throwable {
                        if (arg == null) {
                            return Memory.NULL;
                        }
                        Constructor<BaseWrapper> constructorContext = finalConstructor;
                        Class<? extends BaseWrapper> wrapperClassContext = wrapperClass;
                        if (arg.getClass() != type) {
                            wrapperClassContext = wrappers.get(arg.getClass());
                        }
                        if (wrapperClassContext != null && wrapperClassContext != wrapperClass) {
                            constructorContext = (Constructor<BaseWrapper>) wrapperClassContext.getConstructor(Environment.class, arg.getClass());
                        }
                        try {
                            BaseWrapper instance = constructorContext.newInstance(env, arg);
                            return ObjectMemory.valueOf(instance.__getOriginInstance());
                        } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
                            throw new CriticalException(e);
                        }
                    }

                    @Override
                    public void applyTypeHinting(ParameterEntity parameter) {
                        parameter.setTypeNativeClass(type);
                    }
                };
            } else if (IObject.class.isAssignableFrom(type)) {
                return new MemoryOperation() {

                    @Override
                    public Class<?>[] getOperationClasses() {
                        return new Class<?>[] { IObject.class };
                    }

                    @Override
                    @SuppressWarnings("unchecked")
                    public Object convert(Environment env, TraceInfo trace, Memory arg) throws Throwable {
                        if (arg.isNull()) {
                            return null;
                        }
                        return arg.toObject((Class<? extends IObject>) type);
                    }

                    @Override
                    public Memory unconvert(Environment env, TraceInfo trace, Object arg) throws Throwable {
                        if (arg == null) {
                            return Memory.NULL;
                        }
                        return ObjectMemory.valueOf((IObject) arg);
                    }

                    @Override
                    public void applyTypeHinting(ParameterEntity parameter) {
                        parameter.setType(ReflectionUtils.getClassName(type));
                    }
                };
            } else {
                Class<?> superType = type.getSuperclass();
                if (Object.class != superType && (includeParents || type.isAnonymousClass())) {
                    return get(superType, type.getGenericSuperclass(), includeParents);
                }
            }
        }
    }
    if (operation == null) {
        return null;
    }
    if (genericTypes instanceof ParameterizedType) {
        return operation.instance(((ParameterizedType) genericTypes).getActualTypeArguments());
    }
    return operation;
}
Also used : Memory(php.runtime.Memory) ObjectMemory(php.runtime.memory.ObjectMemory) StringMemory(php.runtime.memory.StringMemory) ParameterizedType(java.lang.reflect.ParameterizedType) BaseWrapper(php.runtime.lang.BaseWrapper) IObject(php.runtime.lang.IObject) Constructor(java.lang.reflect.Constructor) TraceInfo(php.runtime.env.TraceInfo) IterableMemoryOperation(php.runtime.memory.support.operation.iterator.IterableMemoryOperation) PropertiesMemoryOperation(php.runtime.memory.support.operation.map.PropertiesMemoryOperation) HashMapMemoryOperation(php.runtime.memory.support.operation.map.HashMapMemoryOperation) SetMemoryOperation(php.runtime.memory.support.operation.collection.SetMemoryOperation) MapMemoryOperation(php.runtime.memory.support.operation.map.MapMemoryOperation) HashSetMemoryOperation(php.runtime.memory.support.operation.collection.HashSetMemoryOperation) ListMemoryOperation(php.runtime.memory.support.operation.collection.ListMemoryOperation) CriticalException(php.runtime.exceptions.CriticalException) InvocationTargetException(java.lang.reflect.InvocationTargetException) ParameterEntity(php.runtime.reflection.ParameterEntity) Environment(php.runtime.env.Environment) IObject(php.runtime.lang.IObject)

Example 2 with BaseWrapper

use of php.runtime.lang.BaseWrapper in project jphp by jphp-compiler.

the class ClassWrapper method onWrapMethods.

protected void onWrapMethods(ClassEntity classEntity) {
    Reflection.WrapInterface interfaces = nativeClass.getAnnotation(Reflection.WrapInterface.class);
    Set<Class<?>> wrapInterfaces = new HashSet<Class<?>>();
    if (interfaces != null) {
        wrapInterfaces.addAll(Arrays.asList(interfaces.value()));
    }
    for (Class<?> cls : nativeClass.getDeclaredClasses()) {
        if (cls.getSimpleName().equals("WrappedInterface") && cls.getDeclaringClass() == nativeClass) {
            if (!cls.isInterface()) {
                throw new CriticalException("WrappedInterface class must be interface");
            }
            if (!BaseWrapper.class.isAssignableFrom(nativeClass)) {
                throw new CriticalException("To use WrappedInterface, your class must be inheritances from the BaseWrapper class");
            }
            wrapInterfaces.add(cls);
            break;
        }
    }
    if (!wrapInterfaces.isEmpty() && BaseWrapper.class.isAssignableFrom(nativeClass)) {
        Class<?> bindClass = MemoryOperation.getClassOfWrapper((Class<? extends php.runtime.lang.BaseWrapper<Object>>) nativeClass);
        for (Class _interface : wrapInterfaces) {
            for (Method method : _interface.getDeclaredMethods()) {
                try {
                    if (method.isAnnotationPresent(Reflection.Property.class)) {
                        String name = method.getName();
                        MethodEntity getterEntity;
                        try {
                            getterEntity = onWrapWrapCompileMethod(classEntity, bindClass.getMethod("get" + name.substring(0, 1).toUpperCase() + name.substring(1)), method, false);
                        } catch (NoSuchMethodException e) {
                            if (method.getReturnType() == Boolean.TYPE || method.getReturnType() == Boolean.class) {
                                getterEntity = onWrapWrapCompileMethod(classEntity, bindClass.getMethod("is" + name.substring(0, 1).toUpperCase() + name.substring(1)), method, false);
                            } else {
                                throw e;
                            }
                        }
                        MethodEntity setterEntity = null;
                        try {
                            setterEntity = onWrapWrapCompileMethod(classEntity, bindClass.getMethod("set" + name.substring(0, 1).toUpperCase() + name.substring(1), method.getReturnType()), method, false);
                        } catch (NoSuchMethodException e) {
                        // nop
                        }
                        String propertyName = method.getAnnotation(Reflection.Property.class).value();
                        if (propertyName.isEmpty()) {
                            propertyName = name;
                        }
                        PropertyEntity propertyEntity = getPropertyOfMethod(getterEntity, propertyName);
                        propertyEntity.setGetter(getterEntity);
                        propertyEntity.setSetter(setterEntity);
                        if (setterEntity != null && method.isAnnotationPresent(Reflection.Nullable.class)) {
                            ParameterEntity setterArg = setterEntity.getParameters(1)[0];
                            setterArg.setNullable(true);
                        }
                        if (_interface.isInterface()) {
                            getterEntity.setAbstractable(false);
                            getterEntity.setAbstract(false);
                            if (getterEntity.isPublic()) {
                                getterEntity.setModifier(php.runtime.common.Modifier.PROTECTED);
                            }
                            if (setterEntity != null) {
                                setterEntity.setAbstractable(false);
                                setterEntity.setAbstract(false);
                                if (setterEntity.isPublic()) {
                                    setterEntity.setModifier(php.runtime.common.Modifier.PROTECTED);
                                }
                            }
                        }
                        classEntity.addProperty(propertyEntity).check(null);
                    } else {
                        MethodEntity entity = onWrapWrapCompileMethod(classEntity, bindClass.getDeclaredMethod(method.getName(), method.getParameterTypes()), method, interfaces != null && interfaces.skipConflicts());
                        if (_interface.isInterface()) {
                            entity.setAbstractable(false);
                            entity.setAbstract(false);
                        }
                    }
                } catch (NoSuchMethodException e) {
                    boolean _throw = true;
                    if (interfaces != null && interfaces.skipConflicts()) {
                        for (Class<?> aClass : interfaces.value()) {
                            if (aClass == _interface) {
                                _throw = false;
                            }
                        }
                    }
                    if (_throw) {
                        throw new CriticalException(e);
                    }
                }
            }
        }
    }
    for (Method method : nativeClass.getDeclaredMethods()) {
        Reflection.Signature signature = getSignature(method);
        if (signature != null || method.isAnnotationPresent(Reflection.Getter.class) || method.isAnnotationPresent(Reflection.Setter.class)) {
            Class<?>[] types = method.getParameterTypes();
            if (method.getReturnType() == Memory.class && types.length == 2 && types[0] == Environment.class && types[1] == Memory[].class) {
                onWrapMethod(classEntity, method);
            } else {
                onWrapCompileMethod(classEntity, method);
            }
        }
    }
}
Also used : Memory(php.runtime.Memory) Reflection(php.runtime.annotation.Reflection) Method(java.lang.reflect.Method) CriticalException(php.runtime.exceptions.CriticalException) BaseWrapper(php.runtime.lang.BaseWrapper) IObject(php.runtime.lang.IObject) HashSet(java.util.HashSet)

Aggregations

Memory (php.runtime.Memory)2 CriticalException (php.runtime.exceptions.CriticalException)2 BaseWrapper (php.runtime.lang.BaseWrapper)2 IObject (php.runtime.lang.IObject)2 Constructor (java.lang.reflect.Constructor)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 Method (java.lang.reflect.Method)1 ParameterizedType (java.lang.reflect.ParameterizedType)1 HashSet (java.util.HashSet)1 Reflection (php.runtime.annotation.Reflection)1 Environment (php.runtime.env.Environment)1 TraceInfo (php.runtime.env.TraceInfo)1 ObjectMemory (php.runtime.memory.ObjectMemory)1 StringMemory (php.runtime.memory.StringMemory)1 HashSetMemoryOperation (php.runtime.memory.support.operation.collection.HashSetMemoryOperation)1 ListMemoryOperation (php.runtime.memory.support.operation.collection.ListMemoryOperation)1 SetMemoryOperation (php.runtime.memory.support.operation.collection.SetMemoryOperation)1 IterableMemoryOperation (php.runtime.memory.support.operation.iterator.IterableMemoryOperation)1 HashMapMemoryOperation (php.runtime.memory.support.operation.map.HashMapMemoryOperation)1 MapMemoryOperation (php.runtime.memory.support.operation.map.MapMemoryOperation)1