public static function init() { self::$classSerializableFieldsCache = new IdentityHashMap(); self::$classCustomSerializerCache = new IdentityHashMap(); }
private function classMapToMappedClass($classMap, $cachable = true) { if (null !== $classMap) { $className = $classMap['className']; $_class = new SimpleMappedClass(); // to prevent infinitive recursive loop we cache class before initiate it if ($cachable) { $this->addMappedClassToCache($className, $_class); } $_class->setClassLoader($this->getClassLoader()); $_class->setSignature($className); if (isset($classMap['mappedBy'])) { $_class->setMappedName($classMap['mappedBy']); } else { $_class->setMappedName($className); } if (isset($classMap['isInterface']) && $classMap['isInterface'] == 'true') { $_class->setInterface(true); } if (isset($classMap['isAbstract']) && $classMap['isAbstract'] == 'true') { $_class->setAbstract(true); } //$_class->setPHPClass($this->classLoader->loadClass($classMap['mappedBy'])); $_methods = array(); if (isset($classMap['methods'])) { foreach ($classMap['methods'] as $methodMap) { $_method = new SimpleMappedMethod(); $_retClass = $this->loadMappedClass($methodMap['returnType']); if (isset($methodMap['returnTypeCRC'])) { $_retClass->setCRC($methodMap['returnTypeCRC'], true); } else { $crc = SerializabilityUtil::getSerializationSignature($methodMap['returnType']); if (null !== $crc) { $_retClass->setCRC($crc, false); } } $_method->setReturnType($_retClass); $_method->setMappedName($methodMap['mappedName']); $_method->setName($methodMap['name']); $_params = array(); foreach ($methodMap['params'] as $paramMap) { $_params[] = $this->loadMappedClass($paramMap['type']); } $_method->setParameterTypes($_params); $_method->setDeclaringMappedClass($_class); $_exceptions = array(); if (isset($methodMap['throws'])) { foreach ($methodMap['throws'] as $exceptionMap) { //$_exception = new SimpleMappedField(); $_exception = $this->loadMappedClass($exceptionMap['type']); if (isset($exceptionMap['typeCRC'])) { $_exception->setCRC($exceptionMap['typeCRC'], true); } else { $crc = SerializabilityUtil::getSerializationSignature($exceptionMap['type']); if (null !== $crc) { $_exception->setCRC($crc, false); } // else { // require_once(GWTPHP_DIR.'/maps/com/google/gwt/user/client/rpc/SerializableException.class.php'); // throw new SerializableException("Did not found serialization signature for : " // .$_exception->getName()." in class map file (".$_exception->getName() // .".gwtphpmap.inc.php). Did you forget to put 'typeCRC' value in array map?."); // } } $_exceptions[] = $_exception; } } $_method->setExceptionTypes($_exceptions); $_methods[] = $_method; } } $_class->setMappedMethods($_methods); $_fields = array(); if (isset($classMap['fields'])) { foreach ($classMap['fields'] as $fieldMap) { $_field = new SimpleMappedField(); $_field->setName($fieldMap['name']); $_fieldType = $this->loadMappedClass($fieldMap['type']); if (isset($fieldMap['typeCRC'])) { $_fieldType->setCRC($fieldMap['typeCRC'], true); } else { $crc = SerializabilityUtil::getSerializationSignature($fieldMap['type']); if (null !== $crc) { $_fieldType->setCRC($crc, false); } } $_field->setType($_fieldType); $_field->setDeclaringMappedClass($_class); $_fields[] = $_field; } } $_class->setMappedFields($_fields); if (isset($classMap['extends'])) { $_class->setSuperclass($this->loadMappedClass($classMap['extends'])); } if (isset($classMap['typeCRC'])) { $_class->setCRC($classMap['typeCRC']); } else { $crc = SerializabilityUtil::getSerializationSignature($className); if (null !== $crc) { $_retClass->setCRC($crc, false); } } return $_class; } else { return null; } }
/** * * * @param MappedClass $instanceType * @param ReflectionClass $customFieldSerializer */ private static function putCachedSerializerForClass(MappedClass $instanceType, ReflectionClass $customFieldSerializer = null) { SerializabilityUtil::getClassCustomSerializerCache()->put($instanceType, $customFieldSerializer); }
/** * Enter description here... * * @param MappedClass $mappedClass * @return ReflectionClass */ public static function computeHasCustomFieldSerializer(MappedClass $instanceType) { assert($instanceType != null); $qualifiedTypeName = $instanceType->getName(); // delted // $qualifiedTypeName = null; // if ($instanceType->isArray()) { // /*MappedClass*/ // $componentType = $instanceType->getComponentType(); // // if ($componentType->isPrimitive()) { // $qualifiedTypeName = 'java.lang.'.$componentType->getName(); // // } else { // $qualifiedTypeName = 'java.lang.Object'; // // } // $qualifiedTypeName .= '_Array'; // // } else { // $qualifiedTypeName = $instanceType->getName(); // // } // delted $classLoader = GWTPHPContext::getInstance()->getClassLoader(); $simpleSerializerName = $qualifiedTypeName . "_CustomFieldSerializer"; $customSerializer = SerializabilityUtil::getCustomFieldSerializer($classLoader, $simpleSerializerName); if ($customSerializer != null) { return $customSerializer; } // Try with the regular name /*ReflectionClass*/ $customSerializerClass = SerializabilityUtil::getCustomFieldSerializer($classLoader, SerializabilityUtil::$JRE_SERIALIZER_PACKAGE . '.' . $simpleSerializerName); if ($customSerializerClass != null) { return $customSerializerClass; } return null; }
private function makeObject(Clazz $type, $value) { // no anonymous class, and no local class in php $manualType = $type; $customSerializer = null; do { $customSerializer = SerializabilityUtil::hasCustomFieldSerializer($manualType); if ($customSerializer != null) { break; } $manualType = $manualType->getSuperClass(); } while ($manualType != null); $ins = null; if ($customSerializer != null) { $ins = $this->serializeWithCustomSerializer($customSerializer, $value, $type, $manualType); } else { $ins = new InstantiateCommand($type); $this->identityMap->put($value, $ins); } if ($type != $manualType) { if (!Classes::classOf('GWTSerializable')->isAssignableFrom($type) && !Classes::classOf('IsSerializable')->isAssignableFrom($type)) { throw new SerializationException($type->getName() . ' is not a serializable type'); } } while ($type != $manualType) { $serializableFields = $this->clientOracle->getOperableFields($type); foreach ($serializableFields as $declField) { assert($declField != null); //echo '[' . $declField->getName() . ' = ' . $declField->getType() . ']<br />'; $accessor = Accessors::get($declField->getType()); $valueCommand = null; $fieldValue = $accessor->get($value, $declField); if (is_null($fieldValue)) { $valueCommand = NullValueCommand::INSTANCE(); } else { $fieldType = $declField->getType()->isPrimitive() ? $declField->getType() : ($declField->hasType() ? $declField->getType() : Classes::classOfValue($fieldValue)); $valueCommand = $this->makeValue($fieldType, $fieldValue); } //echo '{set ' . $declField->getDeclaringClass()->getName() . ' / ' . $declField->getName() . ' / ' . $valueCommand . '}'; $ins->set($declField->getDeclaringClass(), $declField->getName(), $valueCommand); } $type = $type->getSuperClass(); } return $ins; }
private function deserializeWithDefaultFieldDeserializer(MappedClass $instanceClass, $instance) { /*MappedField[]*/ $declFields = $instanceClass->getDeclaredFields(); /*MappedField[]*/ $serializableFields = SerializabilityUtil::applyFieldSerializationPolicy($declFields); foreach ($serializableFields as $declField) { $value = $this->deserializeValue($declField->getType()); $propName = $declField->getName(); $rClass = $instanceClass->getReflectionClass(); if ($rClass == null) { throw new ClassNotFoundException('MappedClass: ' . $instanceClass->getSignature() . ' do not contains ReflectionClass infomration'); } if (!$rClass->hasProperty($propName)) { throw new SerializationException('MappedClass: ' . $instanceClass->getSignature() . ' do not contains property: ' . $propName . ' Did you mapped all properties?'); } $rProperty = $rClass->getProperty($propName); if ($rProperty->isPublic()) { $rProperty->setValue($instance, $value); } else { // not public access to property, we try invoke setter method $propNameSetter = 'set' . strtoupper($propName[0]) . substr($propName, 1, strlen($propName)); if (!$rClass->hasMethod($propNameSetter)) { throw new SerializationException('MappedClass: ' . $instanceClass->getSignature() . ' do not contains setter method for private property: ' . $propName . '. Mapped object should be in pojo style?'); } $rMethod = $rClass->getMethod($propNameSetter); if ($rMethod->isPublic()) { $rMethod->invoke($instance, $value); } else { throw new SerializationException('MappedClass: ' . $instanceClass->getSignature() . ' do not contains public setter method for private property: ' . $propName . '. Mapped object should be in pojo style?'); } } /* Object value = deserializeValue(declField.getType()); boolean isAccessible = declField.isAccessible(); boolean needsAccessOverride = !isAccessible && !Modifier.isPublic(declField.getModifiers()); if (needsAccessOverride) { // Override access restrictions declField.setAccessible(true); } declField.set(instance, value); if (needsAccessOverride) { // Restore access restrictions declField.setAccessible(isAccessible); } */ } $superClass = $instanceClass->getSuperclass(); if ($superClass != null && $this->getSerializationPolicy()->shouldDeserializeFields($superClass)) { $this->deserializeImpl(SerializabilityUtil::hasCustomFieldSerializer($superClass), $superClass, $instance); } /* Class<?> superClass = instanceClass.getSuperclass(); if (serializationPolicy.shouldDeserializeFields(superClass)) { deserializeImpl(SerializabilityUtil.hasCustomFieldSerializer(superClass), superClass, instance); } */ }
/** * Instantiable types are primitives, {@line IsSerializable}, types with * custom serializers, and any arrays of those types. Merely * {@link Serializable} types cannot be instantiated or serialized directly * (only as super types of legacy serializable types). * @param MappedClass $mappedClass * @return boolean */ private function isInstantiable(MappedClass $mappedClass) { if ($mappedClass->isPrimitive()) { return true; } if ($mappedClass->isArray()) { return $this->isInstantiable($mappedClass->getComponentType()); } if ($mappedClass->getReflectionClass() != null && $mappedClass->getReflectionClass()->isSubclassOf(SerializationPolicy::$IS_SERIALIZABLE_INTERFACE_CLASS_NAME)) { return true; } //if (IsSerializable.class.isAssignableFrom(clazz)) { // return true; //} return SerializabilityUtil::hasCustomFieldSerializer($mappedClass) != null; }
private function decodeCommand() { $command = $this->next(); if ($command == NL_CHAR) { $command = $this->next(); } $token = $this->token(); switch ($command) { case BOOLEAN_TYPE: $this->pushScalar(new BooleanValueCommand($token == '1')); break; case BYTE_TYPE: $this->pushScalar(new ByteValueCommand(Byte::valueOf($token))); break; case CHAR_TYPE: $this->pushScalar(new CharValueCommand(Character::chr(intval($token)))); break; case DOUBLE_TYPE: $this->pushScalar(new DoubleValueCommand(Double::valueOf($token))); break; case FLOAT_TYPE: $this->pushScalar(new FloatValueCommand(Float::valueOf($token))); break; case INT_TYPE: $this->pushScalar(new IntValueCommand(Integer::valueOf($token))); break; case LONG_TYPE: $this->pushScalar(new LongValueCommand(Long::valueOf($token))); break; case VOID_TYPE: $this->pushScalar(NullValueCommand::INSTANCE()); break; case SHORT_TYPE: $this->pushScalar(new ShortValueCommand(Short::valueOf($token))); break; case STRING_TYPE: // "4~abcd $length = Integer::valueOf($token); $value = $this->nextCount($length); if ($this->next() != RPC_SEPARATOR_CHAR) { throw new RuntimeException('Overran string'); } $this->pushString(new StringValueCommand($value)); break; case ENUM_TYPE: // ETypeSeedName~IOrdinal~ $ordinal = $this->readCommand('IntValueCommand')->getValue(); $clazz = $this->findClass($token); $x = new EnumValueCommand($clazz); $this->pushIdentity($x); $x->setValue($ordinal); break; case ARRAY_TYPE: // Encoded as (leafType, dimensions, length, ...) $leaf = $this->findClass($token); $numDims = $this->readCommand('IntValueCommand')->getValue(); $clazz = null; if ($numDims > 1) { $clazz = ArrayType::clazz($leaf, $numDims); } else { $clazz = $leaf; } $x = new ArrayValueCommand($clazz); $this->pushIdentity($x); $length = $this->readCommand('IntValueCommand')->getValue(); for ($i = 0; $i < $length; $i++) { $x->add($this->readCommand('ValueCommand')); } break; case OBJECT_TYPE: // LTypeSeedName~3... N-many setters ... $clazz = $this->findClass($token); $x = new InstantiateCommand($clazz); $this->pushIdentity($x); $this->readSetters($clazz, $x); break; case INVOKE_TYPE: // !TypeSeedName~Number of objects written by CFS~...CFS objects...~ // Number of extra fields~...N-many setters... $clazz = $this->findClass($token); $serializerClass = null; $manualType = $clazz; while ($manualType != null) { $serializerClass = SerializabilityUtil::hasCustomFieldSerializer($manualType); if ($serializerClass != null) { break; } $manualType = $manualType->getSuperClass(); } if ($serializerClass == null) { throw new IncompatibleRemoteServiceException('Class [' . $clazz->getName() . '] has no custom serializer on server'); } $x = new InvokeCustomFieldSerializerCommand($clazz, $serializerClass, $manualType); $this->pushIdentity($x); $this->readFields($x); $this->readSetters($clazz, $x); break; case RETURN_TYPE: // R4~...values... $this->toReturn = new ReturnCommand(); $toRead = Integer::valueOf($token); for ($i = 0; $i < $toRead; $i++) { $this->toReturn->addValue($this->readCommand('ValueCommand')); } break; case THROW_TYPE: // T...value... $this->toThrow = $this->readCommand('ValueCommand'); break; case BACKREF_TYPE: // @backrefNumber~ $x = $this->backRefs[Integer::valueOf($token)]; assert($x != null); array_push($this->commands, $x); break; case RPC_SEPARATOR_CHAR: throw new RuntimeException('Segmentation overrun at ' + $this->idx); default: throw new RuntimeException('Unknown Command ' + $command); } }
public function getOperableFields(Clazz $clazz) { return SerializabilityUtil::applyFieldSerializationPolicy($clazz); }
/** * * * @param Object $instance * @param MappedClass $instanceClass * @ throws SerializationException */ private function serializeClass($instance, MappedClass $instanceClass) { assert($instance != null); /*MappedField[]*/ $declFields = $instanceClass->getDeclaredFields(); /*MappedField[]*/ $serializableFields = SerializabilityUtil::applyFieldSerializationPolicy($declFields); foreach ($serializableFields as $declField) { assert($declField != null); $value = null; $propName = $declField->getName(); $rClass = $instanceClass->getReflectionClass(); //$rClass = new ReflectionObject($instance); if ($rClass == null) { throw new ClassNotFoundException('MappedClass: ' . $instanceClass->getSignature() . ' do not contains ReflectionClass infomration'); } if (!$rClass->hasProperty($propName)) { throw new SerializationException('MappedClass: ' . $instanceClass->getSignature() . ' do not contains property: ' . $propName . ' Did you mapped all properties?'); } $rProperty = $rClass->getProperty($propName); if ($rProperty->isPublic()) { $value = $rProperty->getValue($instance); } else { // not public access to property, we try invoke getter method $propNameSetter = 'get' . strtoupper($propName[0]) . substr($propName, 1, strlen($propName)); if (!$rClass->hasMethod($propNameSetter)) { throw new SerializationException('MappedClass: ' . $instanceClass->getSignature() . ' do not contains getter method for private property: ' . $propName . '. Mapped object should be in pojo style?'); } $rMethod = $rClass->getMethod($propNameSetter); if ($rMethod->isPublic()) { $value = $rMethod->invoke($instance); } else { throw new SerializationException('MappedClass: ' . $instanceClass->getSignature() . ' do not contains public getter method for private property: ' . $propName . '. Mapped object should be in pojo style?'); } } $this->serializeValue($value, $declField->getType()); } /* assert (instance != null); Field[] declFields = instanceClass.getDeclaredFields(); Field[] serializableFields = SerializabilityUtil.applyFieldSerializationPolicy(declFields); for (Field declField : serializableFields) { assert (declField != null); boolean isAccessible = declField.isAccessible(); boolean needsAccessOverride = !isAccessible && !Modifier.isPublic(declField.getModifiers()); if (needsAccessOverride) { // Override the access restrictions declField.setAccessible(true); } Object value; try { value = declField.get(instance); serializeValue(value, declField.getType()); } catch (IllegalArgumentException e) { throw new SerializationException(e); } catch (IllegalAccessException e) { throw new SerializationException(e); } if (needsAccessOverride) { // Restore the access restrictions declField.setAccessible(isAccessible); } } Class<?> superClass = instanceClass.getSuperclass(); if (serializationPolicy.shouldSerializeFields(superClass)) { serializeImpl(instance, superClass); }*/ $superClass = $instanceClass->getSuperclass(); if ($superClass != null && $this->serializationPolicy->shouldDeserializeFields($superClass)) { $this->serializeImpl($instance, $superClass); } }