| /* |
| * 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 |
| }; |
| |
| 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 |
| |