javolution.context.LocalContext Maven / Gradle / Ivy
Show all versions of javolution-core-java-msftbx
/*
* Javolution - Java(TM) Solution for Real-Time and Embedded Systems
* Copyright (C) 2012 - 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 javolution.context.SecurityContext.Permission;
import javolution.lang.Configurable;
import javolution.osgi.internal.OSGiServices;
/**
* A context holding locally scoped {@link Parameter parameters} values.
* For example, when performing modulo arithmetics the actual modulo
* being used is usually the same for most operations and does not need
* to be specified for each operation.
* [code]
* import javolution.context.LocalContext.Parameter;
* public class ModuloInteger extends Number {
* public static final Parameter MODULO = new Parameter() {
* protected Integer getDefault() { return -1; }
* };
* public ModuloInteger times(ModuloInteger that) { ... }
* }
* LocalContext ctx = LocalContext.enter();
* try {
* ctx.supersede(ModuloInteger.MODULO, 13); // Sets local modulo value.
* x = a.times(b).plus(c.times(d)); // Operations modulo 13
* ...
* } finally {
* ctx.exit(); // Reverts to previous modulo setting.
* }[/code]
*
* As for any context, local context settings are inherited during
* {@link ConcurrentContext} executions.
*
* @author Jean-Marie Dautelle
* @version 6.0 December 12, 2012
*/
public abstract class LocalContext extends AbstractContext {
/**
* A {@link Configurable configurable} parameter whose value can
* be locally superseded within the scope of {@link LocalContext}.
*/
public static abstract class Parameter extends Configurable {
/**
* Holds the general permission to supersede any parameter value
* (action "supersede").
*/
public static final Permission> SUPERSEDE_PERMISSION = new Permission>(
Parameter.class, "supersede");
/**
* Holds this instance supersede permission.
*/
private final Permission> supersedePermission;
/**
* Creates a new parameter (configurable).
*/
public Parameter() {
this.supersedePermission = new Permission>(
Parameter.class, "supersede", this);
}
/**
* Returns the permission to locally supersede the current value
* of this instance.
*/
public Permission> getSupersedePermission() {
return supersedePermission;
}
/**
* Returns the current parameter value (the default value if not
* reconfigured nor {@link LocalContext#supersede superseded}).
*/
public T get() {
LocalContext ctx = current(LocalContext.class);
return (ctx != null) ? ctx.getValue(this, super.get()) : super.get();
}
}
/**
* Default constructor.
*/
protected LocalContext() {}
/**
* Enters and returns a new local context instance.
*/
public static LocalContext enter() {
LocalContext ctx = current(LocalContext.class);
if (ctx == null) { // Root.
ctx = OSGiServices.getLocalContext();
}
return (LocalContext) ctx.enterInner();
}
/**
* Supersedes the value of the specified parameter.
*
* @param param the local parameter whose local value is overridden.
* @param localValue the new local value.
* @throws SecurityException if the permission to override the specified
* parameter is not granted.
* @throws NullPointerException if the specified local value is {@code null}.
*/
public abstract void supersede(Parameter param, T localValue);
/**
* Returns the local value of the specified parameter or the specified
* default value if not {@link LocalContext#supersede superseded}.
*
* @param param the local parameter whose local value is returned.
* @param defaultValue the parameter value if not superseded.
*/
protected abstract T getValue(Parameter param, T defaultValue);
}