// ERCStatic.java
// (c) by Anjo Krank (ak@kcmedia.ag)
package er.corebusinesslogic;
import com.webobjects.eoaccess.EOUtilities;
import com.webobjects.eocontrol.EOEditingContext;
import com.webobjects.eocontrol.EOEnterpriseObject;
import com.webobjects.foundation.NSArray;
import com.webobjects.foundation.NSKeyValueCoding;
import com.webobjects.foundation.NSMutableDictionary;
import er.extensions.eof.ERXEC;
import er.extensions.eof.ERXEOControlUtilities;
import er.extensions.eof.ERXObjectStoreCoordinator;
import er.extensions.foundation.ERXProperties;
/**
*
* FIXME AK this code could be replaced by an ERXEOCache
*
* @property er.corebusinesslogic.ERCStatic.UseSeparateChannel
*/
public class ERCStatic extends _ERCStatic {
/**
* Do I need to update serialVersionUID?
* See section 5.6 <cite>Type Changes Affecting Serialization</cite> on page 51 of the
* <a href="http://java.sun.com/j2se/1.4/pdf/serial-spec.pdf">Java Object Serialization Spec</a>
*/
private static final long serialVersionUID = 1L;
// Class methods go here
public static class ERCStaticClazz extends _ERCStaticClazz {
private NSMutableDictionary _staticsPerKey = new NSMutableDictionary();
public ERCStatic objectMatchingKey(EOEditingContext ec, String key) {
return objectMatchingKey(ec, key, false);
}
public NSArray staticsForKey(EOEditingContext ec, String key) {
return EOUtilities.objectsMatchingKeyAndValue(ec, "ERCStatic", Key.KEY, key);
}
public ERCStatic objectMatchingKey(EOEditingContext ec, String key, boolean noCache) {
// If noCache is true we always go to the database
Object result = noCache ? null : _staticsPerKey.objectForKey(key);
if (result == null) {
NSArray arr = staticsForKey(ec, key);
if (arr.count() > 1)
throw new IllegalStateException("Found " + arr.count() + " rows for key " + key);
result = arr.count() == 1 ? arr.objectAtIndex(0) : NSKeyValueCoding.NullValue;
if (result instanceof EOEnterpriseObject) {
privateEditingContext().lock();
try {
_staticsPerKey.setObjectForKey(ERXEOControlUtilities.localInstanceOfObject(privateEditingContext(), (ERCStatic) result), key);
} finally {
privateEditingContext().unlock();
}
}
result = result == NSKeyValueCoding.NullValue ? null : result;
} else if (result instanceof EOEnterpriseObject) {
privateEditingContext().lock();
try {
result = ERXEOControlUtilities.localInstanceOfObject(ec, (ERCStatic) result);
} finally {
privateEditingContext().unlock();
}
} else if (result.equals(NSKeyValueCoding.NullValue)) {
result = null;
}
return (ERCStatic) result;
}
public void invalidateCache() { _staticsPerKey.removeAllObjects(); }
private static EOEditingContext _privateEditingContext;
private static synchronized EOEditingContext privateEditingContext() {
if (_privateEditingContext == null) {
if (ERXProperties.booleanForKeyWithDefault("er.corebusinesslogic.ERCStatic.UseSeparateChannel", true)) {
_privateEditingContext = ERXEC.newEditingContext(ERXObjectStoreCoordinator.create());
_privateEditingContext.setSharedEditingContext(null);
} else {
_privateEditingContext = ERXEC.newEditingContext();
}
}
return _privateEditingContext;
}
public String staticStoredValueForKey(EOEditingContext ec, String key) {
return staticStoredValueForKey(ec, key, false);
}
public String staticStoredValueForKey(EOEditingContext ec, String key, boolean noCache) {
ERCStatic entry = objectMatchingKey(ec, key, noCache);
return entry != null ? entry.value() : null;
}
public int staticStoredIntValueForKey(EOEditingContext ec, String key) {
return staticStoredIntValueForKey(ec, key, false);
}
public int staticStoredIntValueForKey(EOEditingContext ec, String key, boolean noCache) {
int result = -1;
String s = staticStoredValueForKey(ec, key, noCache);
if (s != null) {
try {
result = Integer.parseInt(s);
} catch (NumberFormatException e) {}
}
return result;
}
public String staticStoredValueForKey(String key, boolean noCache) {
String value = null;
privateEditingContext().lock();
try {
value = staticStoredValueForKey(privateEditingContext(), key, noCache);
} finally {
privateEditingContext().unlock();
}
return value;
}
public String staticStoredValueForKey(String key) {
return staticStoredValueForKey(key, false);
}
public int staticStoredIntValueForKey(String key) {
return staticStoredIntValueForKey(key, false);
}
public int staticStoredIntValueForKey(String key, boolean noCache) {
int value = 0;
privateEditingContext().lock();
try {
value = staticStoredIntValueForKey(privateEditingContext(), key, noCache);
} finally {
privateEditingContext().unlock();
}
return value;
}
public void takeStaticStoredValueForKey(String value,
String key) {
privateEditingContext().lock();
try {
takeStaticStoredValueForKey(privateEditingContext(), value, key);
// Clear out the stacks.
privateEditingContext().saveChanges();
privateEditingContext().revert();
} finally {
privateEditingContext().unlock();
}
}
public void takeStaticStoredValueForKey(EOEditingContext editingContext,
String value,
String key) {
ERCStatic entry = ERCStatic.clazz.objectMatchingKey(editingContext,key);
// AK: this is totally thread unsafe...
if (entry==null) {
entry=(ERCStatic)ERXEOControlUtilities.createAndInsertObject(editingContext, "ERCStatic");
entry.setKey(key);
}
entry.setValue(value);
}
}
public static ERCStaticClazz clazz = new ERCStaticClazz();
@Override
public String toString() {
return entityName()+": "+key()+"="+value();
}
@Override
public String userPresentableDescription() {
return toString();
}
}