/*
 * 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.
 */
package org.apache.geode.pdx;

import java.lang.reflect.Field;
import java.util.Collections;
import java.util.List;
import java.util.Properties;

import org.apache.geode.cache.Cache;
import org.apache.geode.cache.Declarable;
import org.apache.geode.cache.RegionService;
import org.apache.geode.pdx.internal.AutoSerializableManager;

/**
 * This class uses Java reflection in conjunction with {@link org.apache.geode.pdx.PdxSerializer
 * PdxSerialzer} to perform automatic serialization of domain objects. The implication is that the
 * domain classes do not need to implement the <code>PdxSerializable</code> interface.
 * <p>
 * This implementation will serialize all relevant fields
 * <p>
 * For example:
 *
 * <pre>
 * Cache c = new CacheFactory().set(&quot;cache-xml-file&quot;, cacheXmlFileName)
 *     .setPdxSerializer(new ReflectionBasedAutoSerializer("com.foo.DomainObject")).create();
 * </pre>
 * <p>
 * In this example <code>DomainObject</code> would not need to implement
 * <code>PdxSerializable</code> to be serialized.
 * <p>
 * The equivalent <code>cache.xml</code> entries might be as follows:
 *
 * <pre>
 * &lt;pdx&gt;
 *   &lt;pdx-serializer&gt;
 *     &lt;class-name&gt;
 *       org.apache.geode.pdx.ReflectionBasedAutoSerializer
 *     &lt;/class-name&gt;
 *     &lt;parameter name="classes"&gt;
 *       &lt;string&gt; com.company.domain.DomainObject &lt;/string&gt;
 *     &lt;/parameter&gt;
 *   &lt;/pdx-serializer&gt;
 * &lt;/pdx&gt;
 * </pre>
 *
 * See {@link ReflectionBasedAutoSerializer#reconfigure(String...) reconfigure} for additional
 * details on the format of the parameter string.
 *
 * @since GemFire 6.6
 */
public class ReflectionBasedAutoSerializer implements PdxSerializer, Declarable {

  private final AutoSerializableManager manager;

  /**
   * Default constructor primarily used during declarative configuration via the cache.xml file.
   * Instances created with this constructor will not match any classes so use
   * {@link #ReflectionBasedAutoSerializer(String...)} instead.
   */
  public ReflectionBasedAutoSerializer() {
    this(new String[0]);
  }

  /**
   * Constructor which takes a list of class name patterns which are to be auto-serialized.
   * Portability of serialization will not be checked.
   * <p>
   * Each string in the list represents a definition in the following form:
   *
   * <pre>
   *   &lt;class pattern&gt;#identity=&lt;identity field pattern&gt;#exclude=&lt;exclude field pattern&gt;
   * </pre>
   *
   * The hash (#) characters are separators and are not part of the parameter name. An example would
   * be:
   *
   * <pre>
   *   com.company.DomainObject.*#identity=id.*#exclude=creationDate
   * </pre>
   *
   * This would select all classes with a class name beginning with
   * <code>com.company.DomainObject</code> and would select as PDX identity fields any fields
   * beginning with <code>id</code> and would not serialize the field called
   * <code>creationDate</code>.
   * <p>
   * There is no association between the the <i>identity</i> and <i>exclude</i> options, so the
   * above example could also be expressed as:
   *
   * <pre>
   *   com.company.DomainObject.*#identity=id.*
   *   com.company.DomainObject.*#exclude=creationDate
   * </pre>
   *
   * Note that <u>all</u> defined patterns are used when determining whether a field should be
   * considered as an identity field or should be excluded. Thus the order of the patterns is not
   * relevant.
   *
   * @param classes the patterns which are matched against domain class names to determine whether
   *        they should be serialized
   * @deprecated as of 6.6.2 use ReflectionBasedAutoSerializer(String...) instead.
   */
  public ReflectionBasedAutoSerializer(List<String> classes) {
    this(listToArray(classes));
  }

  private static String[] listToArray(List<String> l) {
    if (l == null) {
      l = Collections.emptyList();
    }
    return l.toArray(new String[0]);
  }

  /**
   * Constructor which takes a list of class name patterns which are to be auto-serialized.
   * Portability of serialization will not be checked.
   * <p>
   * Each string in the list represents a definition in the following form:
   *
   * <pre>
   *   &lt;class pattern&gt;#identity=&lt;identity field pattern&gt;#exclude=&lt;exclude field pattern&gt;
   * </pre>
   *
   * The hash (#) characters are separators and are not part of the parameter name. An example would
   * be:
   *
   * <pre>
   *   com.company.DomainObject.*#identity=id.*#exclude=creationDate
   * </pre>
   *
   * This would select all classes with a class name beginning with
   * <code>com.company.DomainObject</code> and would select as PDX identity fields any fields
   * beginning with <code>id</code> and would not serialize the field called
   * <code>creationDate</code>.
   * <p>
   * There is no association between the the <i>identity</i> and <i>exclude</i> options, so the
   * above example could also be expressed as:
   *
   * <pre>
   *   com.company.DomainObject.*#identity=id.*
   *   com.company.DomainObject.*#exclude=creationDate
   * </pre>
   *
   * Note that <u>all</u> defined patterns are used when determining whether a field should be
   * considered as an identity field or should be excluded. Thus the order of the patterns is not
   * relevant.
   *
   * @param patterns the patterns which are matched against domain class names to determine whether
   *        they should be serialized
   * @since GemFire 6.6.2
   */
  public ReflectionBasedAutoSerializer(String... patterns) {
    this(false, patterns);
  }

  /**
   * Constructor which takes a list of class name patterns which are to be auto-serialized.
   * <p>
   * Each string in the list represents a definition in the following form:
   *
   * <pre>
   *   &lt;class pattern&gt;#identity=&lt;identity field pattern&gt;#exclude=&lt;exclude field pattern&gt;
   * </pre>
   *
   * The hash (#) characters are separators and are not part of the parameter name. An example would
   * be:
   *
   * <pre>
   *   com.company.DomainObject.*#identity=id.*#exclude=creationDate
   * </pre>
   *
   * This would select all classes with a class name beginning with
   * <code>com.company.DomainObject</code> and would select as PDX identity fields any fields
   * beginning with <code>id</code> and would not serialize the field called
   * <code>creationDate</code>.
   * <p>
   * There is no association between the the <i>identity</i> and <i>exclude</i> options, so the
   * above example could also be expressed as:
   *
   * <pre>
   *   com.company.DomainObject.*#identity=id.*
   *   com.company.DomainObject.*#exclude=creationDate
   * </pre>
   *
   * Note that <u>all</u> defined patterns are used when determining whether a field should be
   * considered as an identity field or should be excluded. Thus the order of the patterns is not
   * relevant.
   *
   * @param checkPortability if <code>true</code> then an serialization done by this serializer will
   *        throw an exception if the object it not portable to non-java languages.
   * @param patterns the patterns which are matched against domain class names to determine whether
   *        they should be serialized
   * @since GemFire 6.6.2
   */
  public ReflectionBasedAutoSerializer(boolean checkPortability, String... patterns) {
    // We allow this class to escape its constructor so that our delegate can
    // call back to us when needed. Callbacks will not happen until this instance
    // is fully constructed and registered with the Cache.
    this.manager = AutoSerializableManager.create(this, checkPortability, patterns);
  }

  /**
   * Method to configure classes to consider for serialization, to set any identity fields and to
   * define any fields to exclude from serialization.
   * <p>
   * Each string in the list represents a definition in the following form:
   *
   * <pre>
   *   &lt;class pattern&gt;#identity=&lt;identity field pattern&gt;#exclude=&lt;exclude field pattern&gt;
   * </pre>
   *
   * The hash (#) characters are separators and are not part of the parameter name. An example would
   * be:
   *
   * <pre>
   *   com.company.DomainObject.*#identity=id.*#exclude=creationDate
   * </pre>
   *
   * This would select all classes with a class name beginning with
   * <code>com.company.DomainObject</code> and would select as PDX identity fields any fields
   * beginning with <code>id</code> and would not serialize the field called
   * <code>creationDate</code>.
   * <p>
   * There is no association between the the <i>identity</i> and <i>exclude</i> options, so the
   * above example could also be expressed as:
   *
   * <pre>
   *   com.company.DomainObject.*#identity=id.*
   *   com.company.DomainObject.*#exclude=creationDate
   * </pre>
   *
   * Note that <u>all</u> defined patterns are used when determining whether a field should be
   * considered as an identity field or should be excluded. Thus the order of the patterns is not
   * relevant.
   *
   * @param patterns the list of definitions to apply
   * @deprecated as of 6.6.2 use {@link #reconfigure(String...)} instead.
   */
  public void setSerializableClasses(List<String> patterns) {
    reconfigure(listToArray(patterns));
  }

  /**
   * Method to reconfigure this serializer. Any previous configuration is cleared. The serializer
   * will not check for portable serialization.
   * <p>
   * Each string in the list represents a definition in the following form:
   *
   * <pre>
   *   &lt;class pattern&gt;#identity=&lt;identity field pattern&gt;#exclude=&lt;exclude field pattern&gt;
   * </pre>
   *
   * The hash (#) characters are separators and are not part of the parameter name. An example would
   * be:
   *
   * <pre>
   *   com.company.DomainObject.*#identity=id.*#exclude=creationDate
   * </pre>
   *
   * This would select all classes with a class name beginning with
   * <code>com.company.DomainObject</code> and would select as PDX identity fields any fields
   * beginning with <code>id</code> and would not serialize the field called
   * <code>creationDate</code>.
   * <p>
   * There is no association between the the <i>identity</i> and <i>exclude</i> options, so the
   * above example could also be expressed as:
   *
   * <pre>
   *   com.company.DomainObject.*#identity=id.*
   *   com.company.DomainObject.*#exclude=creationDate
   * </pre>
   *
   * Note that <u>all</u> defined patterns are used when determining whether a field should be
   * considered as an identity field or should be excluded. Thus the order of the patterns is not
   * relevant.
   *
   * @param patterns the definitions to apply
   * @since GemFire 6.6.2
   */
  public void reconfigure(String... patterns) {
    reconfigure(false, patterns);
  }

  /**
   * Method to reconfigure this serializer. Any previous configuration is cleared.
   * <p>
   * Each string in the list represents a definition in the following form:
   *
   * <pre>
   *   &lt;class pattern&gt;#identity=&lt;identity field pattern&gt;#exclude=&lt;exclude field pattern&gt;
   * </pre>
   *
   * The hash (#) characters are separators and are not part of the parameter name. An example would
   * be:
   *
   * <pre>
   *   com.company.DomainObject.*#identity=id.*#exclude=creationDate
   * </pre>
   *
   * This would select all classes with a class name beginning with
   * <code>com.company.DomainObject</code> and would select as PDX identity fields any fields
   * beginning with <code>id</code> and would not serialize the field called
   * <code>creationDate</code>.
   * <p>
   * There is no association between the the <i>identity</i> and <i>exclude</i> options, so the
   * above example could also be expressed as:
   *
   * <pre>
   *   com.company.DomainObject.*#identity=id.*
   *   com.company.DomainObject.*#exclude=creationDate
   * </pre>
   *
   * Note that <u>all</u> defined patterns are used when determining whether a field should be
   * considered as an identity field or should be excluded. Thus the order of the patterns is not
   * relevant.
   *
   * @param patterns the definitions to apply
   * @param checkPortability if <code>true</code> then an serialization done by this serializer will
   *        throw an exception if the object it not portable to non-java languages.
   * @since GemFire 6.6.2
   */
  public void reconfigure(boolean checkPortability, String... patterns) {
    this.manager.reconfigure(checkPortability, patterns);
  }

  /**
   * Method implemented from <code>PdxSerializer</code> which performs object serialization.
   *
   * @param obj the object to serialize
   * @param writer the <code>PdxWriter</code> to use when serializing this object
   * @return <code>true</code> if the object was serialized, <code>false</code> otherwise
   */
  @Override
  public boolean toData(Object obj, PdxWriter writer) {
    return manager.writeData(writer, obj);
  }

  /**
   * Method implemented from <code>PdxSerializer</code> which performs object de-serialization.
   *
   * @param clazz the class of the object to re-create
   * @param reader the <code>PdxReader</code> to use when creating this object
   * @return the deserialized object if this serializer handles the given class, null otherwise.
   */
  @Override
  public Object fromData(Class<?> clazz, PdxReader reader) {
    return manager.readData(reader, clazz);
  }

  /**
   * Used for declarative class initialization from cache.xml. The following property may be
   * specified:
   * <ul>
   * <li><b>classes</b> - a comma-delimited list of strings which represent the patterns used to
   * select classes for serialization, patterns to select identity fields and patterns to exclude
   * fields. See {@link ReflectionBasedAutoSerializer#reconfigure(String...) reconfigure} for
   * specifics.</li>
   * <li><b>check-portability</b> - if true then an exception will be thrown if an attempt to
   * serialize data that is not portable to .NET is made.
   *
   * @param props properties used to configure the auto serializer
   * @deprecated as of Geode 1.5 use initialize instead
   */
  @Override
  public void init(Properties props) {
    this.manager.init(props);
  }

  /**
   * Used for declarative class initialization from cache.xml. The following property may be
   * specified:
   * <ul>
   * <li><b>classes</b> - a comma-delimited list of strings which represent the patterns used to
   * select classes for serialization, patterns to select identity fields and patterns to exclude
   * fields. See {@link ReflectionBasedAutoSerializer#reconfigure(String...) reconfigure} for
   * specifics.</li>
   * <li><b>check-portability</b> - if true then an exception will be thrown if an attempt to
   * serialize data that is not portable to .NET is made.
   *
   * @param cache the cache that owns this serializer
   * @param props properties used to configure the auto serializer
   * @since Geode 1.5
   */
  @Override
  public void initialize(Cache cache, Properties props) {
    this.manager.setRegionService(cache);
    this.manager.init(props);
  }

  /**
   * Return a <code>Properties</code> object with a representation of the current config. Depending
   * on how this <code>ReflectionBasedAutoSerializer</code> was configured, the returned property
   * value will have the correct semantics but may differ from the the original configuration
   * string.
   *
   * @return a <code>Properties</code> object
   */
  public Properties getConfig() {
    return this.manager.getConfig();
  }

  /**
   * Controls what classes will be auto serialized by this serializer. Override this method to
   * customize what classes will be auto serialized.
   * <p>
   * The default implementation:
   * <ul>
   * <li>only serializes classes whose name matches one of the patterns
   * <li>excludes classes whose package begins with "org.apache.", "java.", or "javax." unless the
   * system property "gemfire.auto.serialization.no.hardcoded.excludes" is set to "true".
   * <li>excludes classes that do not have a public no-arg constructor
   * <li>excludes enum classes
   * <li>excludes classes that require standard java serialization. A class requires standard java
   * serialization if it extends Externalizable or if it extends Serializable and has either a
   * private writeObject method or a writeReplace method as defined by the java serialization
   * specification.
   * </ul>
   * <p>
   * 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.
   *
   * @param clazz the class that is being considered for auto serialization.
   * @return true if instances of the class should be auto serialized; false if not.
   * @since GemFire 6.6.2
   */
  public boolean isClassAutoSerialized(Class<?> clazz) {
    return this.manager.defaultIsClassAutoSerialized(clazz);
  }

  /**
   * 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.
   * <p>
   * The default implementation:
   * <ul>
   * <li>excludes transient fields
   * <li>excludes static fields
   * <li>excludes any fields that match an "#exclude=" pattern.
   * </ul>
   * All other fields are included.
   * <p>
   * 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.
   *
   * @param f the field being considered for serialization
   * @param clazz the original class being serialized that owns this field. Note that this field may
   *        have been inherited from a super class by this class. If you want to find the class that
   *        declared this field use {@link Field#getDeclaringClass()}.
   * @return true if the field should be serialized as a pdx field; false if it should be ignored.
   * @since GemFire 6.6.2
   */
  public boolean isFieldIncluded(Field f, Class<?> clazz) {
    return this.manager.defaultIsFieldIncluded(f, clazz);
  }

  /**
   * 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 {@link PdxInstance} and that one that will need to be
   * used to access the field when doing a query.
   * <p>
   * The default implementation returns the name obtained from <code>f</code>.
   * <p>
   * 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.
   *
   * @param f the field whose name is returned.
   * @param clazz the original class being serialized that owns this field. Note that this field may
   *        have been inherited from a super class by this class. If you want to find the class that
   *        declared this field use {@link Field#getDeclaringClass()}.
   * @return the name of the field
   * @since GemFire 6.6.2
   */
  public String getFieldName(Field f, Class<?> clazz) {
    return f.getName();
  }

  /**
   * 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 {@link PdxInstance} computes its hash code and checks
   * to see if it is equal to another object.
   * <p>
   * The default implementation only marks fields that match an "#identity=" pattern as identity
   * fields.
   * <p>
   * 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.
   *
   * @param f the field to test to see if it is an identity field.
   * @param clazz the original class being serialized that owns this field. Note that this field may
   *        have been inherited from a super class by this class. If you want to find the class that
   *        declared this field use {@link Field#getDeclaringClass()}.
   * @return true if the field should be marked as an identity field; false if not.
   * @since GemFire 6.6.2
   */
  public boolean isIdentityField(Field f, Class<?> clazz) {
    return this.manager.defaultIsIdentityField(f, clazz);
  }

  /**
   * 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.
   * <p>
   * The default implementation uses {@link FieldType#get(Class)} by passing it
   * {@link Field#getType()}.
   * <p>
   * 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.
   *
   * @param f the field whose pdx field type needs to be determined
   * @param clazz the original class being serialized that owns this field. Note that this field may
   *        have been inherited from a super class by this class. If you want to find the class that
   *        declared this field use {@link Field#getDeclaringClass()}.
   * @return the pdx field type of the given domain class field.
   * @since GemFire 6.6.2
   */
  public FieldType getFieldType(Field f, Class<?> clazz) {
    return this.manager.defaultGetFieldType(f, clazz);
  }

  /**
   * Controls if a pdx field's value can be transformed during serialization. Override this method
   * to customize what fields can have their values transformed. If you return true then you need to
   * also override {@link #writeTransform} and {@link #readTransform}.
   * <p>
   * The default implementation returns false.
   * <p>
   * 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.
   *
   * @param f the field in question
   * @param clazz the original class being serialized that owns this field. Note that this field may
   *        have been inherited from a super class by this class. If you want to find the class that
   *        declared this field use {@link Field#getDeclaringClass()}.
   * @return true if the {@link #writeTransform} and {@link #readTransform} need to be called when
   *         serializing and deserializing this field's value.
   * @since GemFire 6.6.2
   */
  public boolean transformFieldValue(Field f, Class<?> clazz) {
    return false;
  }

  /**
   * Controls what field value is written during auto serialization. Override this method to
   * customize the data that will be written during auto serialization. This method will only be
   * called if {@link #transformFieldValue} returned true.
   *
   * @param f the field in question
   * @param clazz the original class being serialized that owns this field. Note that this field may
   *        have been inherited from a super class by this class. If you want to find the class that
   *        declared this field use {@link Field#getDeclaringClass()}.
   * @param originalValue the value of the field that was read from the domain object.
   * @return the actual value to write for this field. Return <code>originalValue</code> if you
   *         decide not to transform the value.
   * @since GemFire 6.6.2
   */
  public Object writeTransform(Field f, Class<?> clazz, Object originalValue) {
    return originalValue;
  }

  /**
   * 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.
   *
   * @param f the field in question
   * @param clazz the original class being serialized that owns this field. Note that this field may
   *        have been inherited from a super class by this class. If you want to find the class that
   *        declared this field use {@link Field#getDeclaringClass()}.
   * @param serializedValue the value of the field that was serialized for this field.
   * @return the actual value to write for this field. Return <code>serializedValue</code> if you
   *         decide not to transform the value.
   * @since GemFire 6.6.2
   */
  public Object readTransform(Field f, Class<?> clazz, Object serializedValue) {
    return serializedValue;
  }

  /**
   * Returns the cache that this serializer is installed on. Returns null if it is not installed.
   *
   * @since GemFire 6.6.2
   */
  public RegionService getRegionService() {
    return this.manager.getRegionService();
  }

  /**
   * For internal use only.
   *
   * @since GemFire 8.2
   */
  public Object getManager() {
    // The result is not AutoSerializableManager because
    // that class is not part of our public APIs.
    return this.manager;
  }
}
