blob: 5ba876b6681679cccc83f45f72b7357cd79d3754 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "geode_defs.hpp"
#include "IPdxSerializer.hpp"
#include "PdxIdentityFieldAttribute.hpp"
using namespace System;
using namespace System::Reflection;
using namespace System::Reflection::Emit;
namespace Apache
{
namespace Geode
{
namespace Client
{
/// <summary>
/// Enumerated type for pdx FieldType
/// </summary>
public enum class FieldType
{
BOOLEAN,
BYTE,
CHAR,
SHORT,
INT,
LONG,
FLOAT,
DOUBLE,
DATE,
STRING,
OBJECT,
BOOLEAN_ARRAY,
CHAR_ARRAY,
BYTE_ARRAY,
SHORT_ARRAY,
INT_ARRAY,
LONG_ARRAY,
FLOAT_ARRAY,
DOUBLE_ARRAY,
STRING_ARRAY,
OBJECT_ARRAY,
ARRAY_OF_BYTE_ARRAYS,
SBYTE,
USHORT,
UINT,
ULONG,
SBYTE_ARRAY,
USHORT_ARRAY,
UINT_ARRAY,
ULONG_ARRAY,
GUID,
DECIMAL
};
ref class FieldWrapper;
/// <summary>
/// This class uses .NET reflection in conjunction with
/// <see cref="IPdxSerializer"/> to perform
/// automatic serialization of domain objects. The implication is that the domain
/// classes do not need to implement the <see cref="IPdxSerializable"> interface.
/// This implementation will serialize all relevant fields.
/// This will not serialize the fields which has defined attribute NonSerialized.
/// This will not serialize the static, literal and readonly fields.
///
/// Use <see cref="PdxIdentityFieldAttribute"> to define member field as identity field.
/// Identity fields are used for hashcode creation and equals methods.
///
/// </summary>
public ref class ReflectionBasedAutoSerializer : IPdxSerializer
{
public:
virtual bool ToData( Object^ o,IPdxWriter^ writer );
virtual Object^ FromData(String^ o, IPdxReader^ reader );
/// <summary>
/// Controls the field name that will be used in pdx for a field being auto serialized.
/// Override this method to customize the field names that will be generated by auto serialization.
/// It allows you to convert a local, language dependent name, to a more portable name.
/// The returned name is the one that will show up in a <see cref="IPdxInstance" /> and that
/// one that will need to be used to access the field when doing a query.
/// <para>
/// The default implementation returns the name obtained from <code>fi</code>.
/// <para>
/// This method is only called the first time it sees a new class. The result
/// will be remembered and used the next time the same class is seen.
/// </summary>
/// <param name="fi"> the field whose name is returned.</param>
/// <param name"type"> type the original class being serialized that owns this field.</param>
/// <returns> the name of the field </returns>
virtual String^ GetFieldName(FieldInfo^ fi, Type^ type);
/// <summary>
/// Controls what fields of a class that is auto serialized will be marked
/// as pdx identity fields.
/// Override this method to customize what fields of an auto serialized class will be
/// identity fields.
/// Identity fields are used when a <see cref="IPdxInstance" /> computes its hash code
/// and checks to see if it is equal to another object.
/// <para>
/// The default implementation only marks fields that match an "#identity=" pattern
/// as identity fields.
/// <para>
/// This method is only called the first time it sees a new class. The result
/// will be remembered and used the next time the same class is seen.
/// </summary>
/// <param name="fi"> the field to test to see if it is an identity field.</param>
/// <param name="type"> the original class being serialized that owns this field.</param>
/// <returns> true if the field should be marked as an identity field; false if not. </returns>
virtual bool IsIdentityField(FieldInfo^ fi, Type^ type);
/// <summary>
/// Controls what pdx field type will be used when auto serializing.
/// Override this method to customize what pdx field type will be used
/// for a given domain class field.
/// <para>
/// The default implementation uses type of field.
/// <para>
/// This method is only called the first time it sees a new class. The result
/// will be remembered and used the next time the same class is seen.
/// </summary>
/// <param name="fi"> the field whose pdx field type needs to be determined </param>
/// <param name="type"> the original class being serialized that owns this field.</param>
/// <returns> the pdx field type of the given domain class field.</returns>
virtual FieldType GetFieldType(FieldInfo^ fi, Type^ type);
/// <summary>
/// Controls what fields of a class will be auto serialized by this serializer.
/// Override this method to customize what fields of a class will be auto serialized.
/// The default implementation:
/// <list type="bullet">
/// <item>
/// <description> excludes NonSerialized fields</description>
/// </item>
/// <item>
/// <description> excludes static fields</description>
/// </item>
/// <item>
/// <description> excludes literal fields</description>
/// </item>
/// <item>
/// <description> excludes readonly fields </description>
/// </item>
/// </list>
/// All other fields are included.
/// This method is only called the first time it sees a new class. The result
/// will be remembered and used the next time the same class is seen.
/// </summary>
/// <param name="fi"> the field being considered for serialization</param>
/// <param name="type"> the original class being serialized that owns this field.</param>
/// <returns> true if the field should be serialized as a pdx field; false if it should be ignored.</returns>
virtual bool IsFieldIncluded(FieldInfo^ fi, Type^ type);
/// <summary>
/// Controls what field value is written during auto serialization.
/// Override this method to customize the data that will be written
/// during auto serialization.
/// </summary>
/// <param name="fi"> the field in question</param>
/// <param name="type"> the original class being serialized that owns this field.</param>
/// <param name="originalValue"> the value of the field that was read from the domain object.</param>
/// <returns> the actual value to write for this field. Return <code>originalValue</code>
/// if you decide not to transform the value. </returns>
virtual Object^ WriteTransform(FieldInfo^ fi, Type^ type, Object^ originalValue);
/// <summary>
/// Controls what field value is read during auto deserialization.
/// Override this method to customize the data that will be read
/// during auto deserialization.
/// This method will only be called if {@link #transformFieldValue}
/// returned true.
/// </summary>
/// <param name="fi"> the field in question </param>
/// <param name="type"> the original class being serialized that owns this field.
/// Note that this field may have been inherited from a super class by this class.</param>
/// <param value="serializeValue"> the value of the field that was serialized for this field.</param>
/// <returns> the actual value to write for this field. Return <code>serializedValue</code>
/// if you decide not to transform the value. </returns>
virtual Object^ ReadTransform(FieldInfo^ fi, Type^ type, Object^ serializeValue);
/// <summary>
/// Overirde this method to create default instance of <code>className</code>
/// Otherwise it will create instance using zer arg public constructor
/// </summary>
/// <param name="className"> name of the class to create default instance </param>
/// <returns> the defaulf instance </returns>
virtual Object^ CreateObject(String^ className, Cache^ cache);
ReflectionBasedAutoSerializer();
private:
FieldType getPdxFieldType( Type^ type);
void serializeFields(Object^ o,IPdxWriter^ writer );
Object^ deserializeFields(String^ o, IPdxReader^ reader);
bool IsPdxIdentityField(FieldInfo^ fi);
System::Collections::Generic::Dictionary<String^, List<FieldWrapper^>^>^ classNameVsFieldInfoWrapper;
List<FieldWrapper^>^ GetFields(Type^ domaimType);
static Type^ PdxIdentityFieldAttributeType = nullptr;
};
} // namespace Client
} // namespace Geode
} // namespace Apache