<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">/*-
 * See the file LICENSE for redistribution information.
 *
 * Copyright (c) 2002-2009 Oracle.  All rights reserved.
 *
 * $Id$
 */

package com.sleepycat.persist.model;

import com.sleepycat.persist.evolve.Converter; // for javadoc
import com.sleepycat.persist.raw.RawStore; // for javadoc

/**
 * Implemented by a proxy class to represent the persistent state of a
 * (non-persistent) proxied class.  Normally classes that are outside the scope
 * of the developer's control must be proxied since they cannot be annotated,
 * and because it is desirable to insulate the stored format from changes to
 * the instance fields of the proxied class.  This is useful for classes in the
 * standard Java libraries, for example.
 *
 * &lt;p&gt;{@code PersistentProxy} objects are not required to be thread-safe.  A
 * single thread will create and call the methods of a given {@code
 * PersistentProxy} object.&lt;/p&gt;
 *
 * &lt;p&gt;There are three requirements for a proxy class:&lt;/p&gt;
 * &lt;ol&gt;
 * &lt;li&gt;It must implement the &lt;code&gt;PersistentProxy&lt;/code&gt; interface.&lt;/li&gt;
 * &lt;li&gt;It must be specified as a persistent proxy class in the entity model.
 * When using the {@link AnnotationModel}, a proxy class is indicated by the
 * {@link Persistent} annotation with the {@link Persistent#proxyFor}
 * property.&lt;/li&gt;
 * &lt;li&gt;It must be explicitly registered by calling {@link
 * EntityModel#registerClass} before opening the store.&lt;/li&gt;
 * &lt;/ol&gt;
 *
 * &lt;p&gt;In order to serialize an instance of the proxied class before it is
 * stored, an instance of the proxy class is created.  The proxied instance is
 * then passed to the proxy's {@link #initializeProxy initializeProxy} method.
 * When this method returns, the proxy instance contains the state of the
 * proxied instance.  The proxy instance is then serialized and stored in the
 * same way as for any persistent object.&lt;/p&gt;
 *
 * &lt;p&gt;When an instance of the proxy object is deserialized after it is
 * retrieved from storage, its {@link #convertProxy} method is called.  The
 * instance of the proxied class returned by this method is then returned as a
 * field in the persistent instance.&lt;/p&gt;
 *
 * &lt;p&gt;For example:&lt;/p&gt;
 * &lt;pre class="code"&gt;
 *  import java.util.Locale;
 *
 *  {@literal @Persistent(proxyFor=Locale.class)}
 *  class LocaleProxy implements {@literal PersistentProxy&lt;Locale&gt;} {
 *
 *      String language;
 *      String country;
 *      String variant;
 *
 *      private LocaleProxy() {}
 *
 *      public void initializeProxy(Locale object) {
 *          language = object.getLanguage();
 *          country = object.getCountry();
 *          variant = object.getVariant();
 *      }
 *
 *      public Locale convertProxy() {
 *          return new Locale(language, country, variant);
 *      }
 *  }&lt;/pre&gt;
 *
 * &lt;p&gt;The above definition allows the {@code Locale} class to be used in any
 * persistent class, for example:&lt;/p&gt;
 * &lt;pre class="code"&gt;
 *  {@literal @Persistent}
 *  class LocalizedText {
 *      String text;
 *      Locale locale;
 *  }&lt;/pre&gt;
 *
 * &lt;p&gt;A proxied class may not be used as a superclass for a persistent class or
 * entity class.  For example, the following is not allowed.&lt;/p&gt;
 * &lt;pre class="code"&gt;
 *  {@literal @Persistent}
 *  class LocalizedText extends Locale { // NOT ALLOWED
 *      String text;
 *  }&lt;/pre&gt;
 *
 * &lt;p&gt;A proxy for proxied class P does not handle instances of subclasses of P.
 * To proxy a subclass of P, a separate proxy class is needed.&lt;/p&gt;
 *
 * &lt;p&gt;Several {@link &lt;a href="Entity.html#proxyTypes"&gt;built in proxy types&lt;/a&gt;}
 * are used implicitly.  An application defined proxy will be used instead of a
 * built-in proxy, if both exist for the same proxied class.&lt;/p&gt;
 *
 * &lt;p&gt;With respect to class evolution, a proxy instance is no different than
 * any other persistent instance.  When using a {@link RawStore} or {@link
 * Converter}, only the raw data of the proxy instance will be visible.  Raw
 * data for the proxied instance never exists.&lt;/p&gt;
 *
 * &lt;p&gt;Currently a proxied object may not contain a reference to itself.  For
 * simple proxied objects such as the Locale class shown above, this naturally
 * won't occur.  But for proxied objects that are containers -- the built-in
 * Collection and Map classes for example -- this can occur if the container is
 * added as an element of itself.  This should be avoided.  If an attempt to
 * store such an object is made, an {@code IllegalArgumentException} will be
 * thrown.&lt;/p&gt;
 *
 * &lt;p&gt;Note that a proxy class may not be a subclass of an entity class.&lt;/p&gt;
 *
 * @author Mark Hayes
 */
public interface PersistentProxy&lt;T&gt; {

    /**
     * Copies the state of a given proxied class instance to this proxy
     * instance.
     */
    void initializeProxy(T object);

    /**
     * Returns a new proxied class instance to which the state of this proxy
     * instance has been copied.
     */
    T convertProxy();
}
</pre></body></html>