private function deserializeClass(Clazz $instanceClass, $instance) { /** * A map from field names to corresponding setter methods. The reference * will be null for classes that do not require special handling for * server-only fields. */ $setters = null; /** * A list of fields of this class known to the client. If null, assume the class is not * enhanced and don't attempt to deal with server-only fields. */ $clientFieldNames = $this->serializationPolicy->getClientFieldNamesForEnhancedClass($instanceClass); if (!is_null($clientFieldNames)) { // Read and set server-only instance fields encoded in RPC data try { $encodedData = $this->readString(); if (!is_null($encodedData)) { $serializedData = Base64Utils::fromBase6($encodedData); $ois = new ObjectInputStream($serializedData); $count = $ois->readInt(); for ($i = 0; $i < $count; $i++) { $fieldName = $ois->readString(); $fieldValue = $ois->readObject(); $field = $instanceClass->getField($fieldName); $field->setAccessible(true); $field->setValue($instance, $fieldValue); } } } catch (Exception $e) { throw new SerializationException($e); } $setters = $this->getSetters($instanceClass); } $serializableFields = SerializabilityUtilEx::applyFieldSerializationPolicy($instanceClass); foreach ($serializableFields as $declField) { assert(!is_null($declField)); if (!is_null($clientFieldNames) && !$clientFieldNames->contains($declField->getName())) { continue; } assert($declField->hasType()); $value = $this->deserializeValue($declField->getType()); $fieldName = $declField->getName(); $setter = null; /* * If setters is non-null and there is a setter method for the given * field, call the setter. Otherwise, set the field value directly. For * persistence APIs such as JDO, the setter methods have been enhanced to * manipulate additional object state, causing direct field writes to fail * to update the object state properly. */ if (!is_null($setters) && !is_null($setters = $setters->get($fieldName))) { $setter->invoke($instance, $value); } else { $isAccessible = $declField->isAccessible(); $needsAccessOverride = !$isAccessible && !$declField->isPublic(); if ($needsAccessOverride) { // Override access restrictions $declField->setAccessible(true); } $declField->setValue($instance, $value); } } $superClass = $instanceClass->getSuperClass(); if ($this->serializationPolicy->shouldDeserializeFields($superClass)) { $this->deserializeImpl(SerializabilityUtilEx::hasCustomFieldSerializer($superClass), $superClass, $instance); } }
private function serializeImpl($instance, Clazz $instanceClass) { assert(!is_null($instance)); $customSerializer = SerializabilityUtilEx::hasCustomFieldSerializer($instanceClass); if (!is_null($customSerializer)) { // Use custom field serializer $customFieldSerializer = SerializabilityUtilEx::loadCustomFieldSerializer($customSerializer); if (is_null($customFieldSerializer)) { $this->serializeWithCustomSerializer($customSerializer, $instance, $instanceClass); } else { $customFieldSerializer->serializeInstance($this, $instance); } } else { if ($instanceClass->isArray()) { $this->serializeArray($instanceClass, $instance); } else { if ($instanceClass->isEnum()) { $this->writeInt($instance); } else { // Regular class instance $this->serializeClass($instance, $instanceClass); } } } }