/* This file is part of the db4o object database http://www.db4o.com
Copyright (C) 2004 - 2011 Versant Corporation http://www.versant.com
db4o is free software; you can redistribute it and/or modify it under
the terms of version 3 of the GNU General Public License as published
by the Free Software Foundation.
db4o is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program. If not, see http://www.gnu.org/licenses/. */
package com.db4o.ta;
import com.db4o.activation.*;
/**
* The Activatable interface must be implemented by classes in order to support transparent
* activation/persistence.<br>
* <br>
*
* The Activatable interface may be added to persistent classes by hand or by
* using the db4o enhancer. For further information on the enhancer see the
* chapter "Enhancement" in the db4o reference documentation.<br>
* <br>
*
* The basic idea for Transparent Activation is:<br>
* Objects have an activation depth of 0, so they are not activated
* at all. Whenever a method is called on such an object, the first thing to do
* before actually executing the method body is to activate the object to
* populating its direct members.<br>
* <br>
*
* To illustrate this approach, we will use the following simple class.<br>
* <pre class="prettyprint"><code>
* public class Item {
* private Item next;
*
* public Item(Item next) {
* this.next = next;
* }
*
* public Item next() {
* return next;
* }
* public void setNext(Item itemToBeSet) {
* this.next = itemToBeSet;
* }
* // ...
* }</code></pre>
*
* The basic sequence of actions to get the above scheme to work is the
* following:<br>
* <br>
*
* Whenever an object is instantiated from db4o, the database registers an
* activator for this object. To enable this, the object has to implement the
* Activatable interface and provide the according bind(Activator) method. The
* default implementation of the bind method will simply store the given
* activator reference for later use.<br>
* <pre class="prettyprint"><code>
* public class Item implements Activatable {
* private Item next;
* private transient Activator activator;
*
* public void bind(Activator activator) {
* if (this.activator == activator) {
* return;
* }
* if (activator != null && null != this.activator) {
* throw new IllegalStateException("Object can only be bound to one activator");
* }
* this.activator = activator;
* }
* public void activate(ActivationPurpose activationPurpose) {
* if(null!=activator){
* activator.activate(activationPurpose);
* }
* }
* // ...
* }</code></pre>
*
* The first action in every method body of an activatable object should be a
* call to the corresponding Activator's activate() method with the given purpose.
* If the method is reading the purpose should be {@link ActivationPurpose#READ},
* for writing {@link ActivationPurpose#WRITE}. <br>
* <pre class="prettyprint"><code>
* public class Item implements Activatable {
* private Item next;
* private transient Activator activator;
*
* public void bind(Activator activator) {
* if (this.activator == activator) {
* return;
* }
* if (activator != null && null != this.activator) {
* throw new IllegalStateException("Object can only be bound to one activator");
* }
* this.activator = activator;
* }
* public void activate(ActivationPurpose activationPurpose) {
* if(null!=activator){
* activator.activate(activationPurpose);
* }
* }
* public Item next() {
* activate(ActivationPurpose.READ);
* return next;
* }
* public void setNext(Item itemToBeSet) {
* activate(ActivationPurpose.Write);
* this.next = itemToBeSet;
* }
* // ...
* }</code></pre>
*
* You always need to call activate() before any data access in the object. Otherwise transparent activation / persistence will not work.
* Since this process is error prone we recommend to use the enhancer tools shipped with db4o.
*
* The activate() method will check whether the object is already activated.
* If this is not the case, it will request the container to activate the object
* to level 1 and set the activated flag accordingly.<br>
* <br>
*
* To instruct db4o to actually use these hooks (i.e. to register the database
* when instantiating an object), {@link TransparentActivationSupport} or {@link TransparentPersistenceSupport} has to be
* registered with the db4o configuration.<br>
* <br>
* <pre class="prettyprint"><code>
* EmbeddedConfiguration config = ... // your configuration
* configuration.common().add(new TransparentActivationSupport());
* </code></pre>
*
* If you implement this interface manually and intend to pass this class through
* the db4o bytecode instrumentation process, make sure you also implement the
* {@link ActivatableInstrumented} marker interface.
*/
public interface Activatable {
/**
* Called by db4o after the object instantiation.
* This method is called to bind the object to the current activator<br/>
* <br/>
* The recommended implementation of this method is to store the passed
* {@link Activator} in a transient field of the object.
*
* @param activator the Activator instance to bind
*/
void bind(Activator activator);
/**
* Should be called by every reading field access of an object. <br/>
* <br/>
* The recommended implementation of this method is to call
* {@link Activator#activate(ActivationPurpose)} on the {@link Activator}
* that was previously passed to {@link #bind(Activator)}.
*
* @param purpose Whereever this object is accessed to read or write. See {@link ActivationPurpose}
*/
void activate(ActivationPurpose purpose);
}