/* * Javolution - Java(TM) Solution for Real-Time and Embedded Systems * Copyright (C) 2006 - Javolution (http://javolution.org/) * All rights reserved. * * Permission to use, copy, modify, and distribute this software is * freely granted, provided that this notice is preserved. */ package javolution.context; import j2me.lang.Comparable; import j2me.util.Map; import javolution.util.FastMap; /** *
This class represents a context persistent accross multiple program * executions. It is typically used to hold * {@link Reference persistent references}.
* *How this context is loaded/saved is application specific. * Although, the simplest way is to use Javolution XML serialization * facility. For example:[code] * import javolution.xml.XMLObjectReader; * import javolution.xml.XMLObjectWriter; * public void main(String[]) { * // Loads persistent context (typically at start-up). * XMLObjectReader reader = XMLObjectReader.newInstance(new FileInputStream("C:/persistent.xml")); * PersistentContext.setCurrent(reader.read(PersistentContext.class)); * ... * ... * // Saves persistent context for future execution. * XMLObjectWriter writer = XMLObjectWriter.newInstance(new FileOutputStream("C:/persistent.xml")); * writer.write(PersistentContext.getCurrent(), PersistentContext.class); * }[/code]
* * @author Jean-Marie Dautelle * @version 4.2, December 31, 2006 */ public class PersistentContext extends Context { /** * Holds the single instance. */ private static PersistentContext _PersistentContext = new PersistentContext(); /** * Holds current id to value mapping. */ private final FastMap _idToValue = new FastMap(); /** * Default constructor. */ public PersistentContext() { } /** * Sets the persistent instance. * * @param ctx the persistent instance. */ public static void setCurrent(PersistentContext ctx) { _PersistentContext = ctx; synchronized (Reference.INSTANCES) { for (FastMap.Entry e = Reference.INSTANCES.head(), end = Reference.INSTANCES.tail(); (e = (FastMap.Entry) e.getNext())!= end;) { Reference reference = (Reference) e.getValue(); if (ctx._idToValue.containsKey(reference._id)) { reference.set(ctx._idToValue.get(reference._id)); } } } } /** * Returns the persistent context instance (singleton). * * @return the persistent context instance. */ public static/*PersistentContext*/Context getCurrent() { return _PersistentContext; } /** * Returns the ID to value mapping for this persistent context. * * @return the persistent value indexed by identifiers. */ public Map/*UnsupportedOperationException
persistent context
* are global to all threads (singleton).
*/
protected void enterAction() {
throw new j2me.lang.UnsupportedOperationException(
"Cannot enter persistent context (already in)");
}
/**
* Throws UnsupportedOperationException
persistent context
* are global to all threads (singleton).
*/
protected void exitAction() {
throw new j2me.lang.UnsupportedOperationException(
"Cannot exit persistent context (always in)");
}
/**
* This class represents a reference over an object which can be kept
* persistent accross multiple program executions. Instances of this class
* are typically used to hold global data time consuming to regenerate.
* For example:[code]
* public class FastMap
Persistent references may also be used to hold optimum configuration
* values set from previous executions. For example:[code]
* public Targets {
* private static PersistentContext.Reference(value.compareTo(this.get()) > 0)
.
*
* @param value the minimum value for this reference.
* @throws IllegalArgumentException if the specified value is not
* {@link Comparable} or an {@link Integer} instance (J2ME).
*/
public void setMinimum(Object/*{T}*/value) {
synchronized (this) {
if (value instanceof Comparable) {
Object prevValue = get();
if (((Comparable) value).compareTo(prevValue) > 0) {
set(value);
}
} else if (value instanceof Integer) {
Object prevValue = get();
if (((Integer) value).intValue() > ((Integer) prevValue)
.intValue()) {
set(value);
}
} else {
throw new IllegalArgumentException();
}
}
}
/**
* Sets this reference to the specified value only if
* (value.compareTo(this.get()) < 0)
.
*
* @param value the maximum value for this reference.
* @throws IllegalArgumentException if the specified value is not
* {@link Comparable} or an {@link Integer} instance (J2ME).
*/
public void setMaximum(Object/*{T}*/value) {
synchronized (this) {
if (value instanceof Comparable) {
Object prevValue = get();
if (((Comparable) value).compareTo(prevValue) < 0) {
set(value);
}
} else if (value instanceof Integer) {
Object prevValue = get();
if (((Integer) value).intValue() < ((Integer) prevValue)
.intValue()) {
set(value);
}
} else {
throw new IllegalArgumentException();
}
}
}
/**
* Returns the string representation of the current value of this
* reference.
*
* @return String.valueOf(this.get())
*/
public String toString() {
return String.valueOf(get());
}
/**
* Notifies this reference that its value has changed (for example
* a new persistent context has been loaded).
* The default implementation does nothing.
*/
protected void notifyChange() {
}
}
}