/*
* $Id: PersistentFileNamespace.java,v 1.7 2002/09/16 08:05:06 jkl Exp $
*
* Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
*
* Use is subject to license terms, as defined in
* Anvil Sofware License, Version 1.1. See LICENSE
* file, or http://njet.org/license-1.1.txt
*/
package anvil.server.file;
import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import anvil.java.util.BindingEnumeration;
import anvil.core.Any;
import anvil.core.Array;
import anvil.core.Serialization;
import anvil.server.PersistentNamespace;
import anvil.server.NamespacePreferences;
import anvil.server.Zone;
import anvil.server.ConfigurationError;
import anvil.script.Context;
/**
* class PersistentFileNamespace
*
* @author: Jani Lehtim�ki
*/
public class PersistentFileNamespace implements PersistentNamespace
{
protected Zone _zone;
protected File _file;
protected boolean _copyonget = false;
protected boolean _copyonset = false;
protected boolean _loaded = false;
protected int _modcount = 0;
protected int _maxmodcount = 100;
protected long _lastmodified = -1;
protected String _name = "";
protected Array _namespace = new Array();
public PersistentFileNamespace()
{
}
public PersistentFileNamespace(Zone zone, String name, File file,
boolean copyonget, boolean copyonset, int maxmodcount)
{
_name = name;
_file = file;
_zone = zone;
_copyonget = copyonget;
_copyonset = copyonset;
_maxmodcount = maxmodcount;
}
public String toString()
{
return "PersistentFileNamespace(" + _name + "@" + _file +")";
}
public String getName()
{
return _name;
}
public void initialize(Zone zone, NamespacePreferences prefs)
{
String filename = (String)prefs.getPreference("file");
if (filename == null) {
throw new ConfigurationError("PersistentFileNamespace requires existends of property 'file'");
}
File file = new File(filename);
_name = prefs.getName();
_file = file;
_zone = zone;
_copyonget = prefs.getBooleanPreference("copyonget", false);
_copyonset = prefs.getBooleanPreference("copyonset", false);
_maxmodcount = prefs.getIntPreference("maxmodifications", 1);
if (_maxmodcount < 1) {
_maxmodcount = 1;
}
_zone.log().info("Namespace " + this + " initialized");
}
public synchronized void remove()
{
_namespace.clear();
_file.delete();
}
public synchronized void commit()
{
save(true);
}
public void stop()
{
save(true);
_zone.log().info("Namespace " + this + " stopped");
}
private void load()
{
if (_file.exists() && _file.canRead()) {
if (!_loaded || (_file.lastModified() > _lastmodified)) {
FileInputStream in = null;
try {
if (_file.length()>0) {
in = new FileInputStream(_file);
Any data = Serialization.unserialize(null, in);
if (data.isArray()) {
_namespace = data.toArray();
}
} else {
_namespace.clear();
}
} catch (Throwable t) {
_zone.log().error(t);
} finally {
if (in != null) {
try {
in.close();
} catch (Throwable t) {
}
}
}
_lastmodified =_file.lastModified();
_loaded = true;
}
}
}
private void save(boolean forcesave)
{
_modcount++;
if (((_modcount%_maxmodcount)==0) || forcesave) {
FileOutputStream out = null;
try {
out = new FileOutputStream(_file);
Serialization.serialize(null, _namespace, out);
} catch (Throwable t) {
_zone.log().error(t);
} finally {
if (out != null) {
try {
out.close();
} catch (Throwable t) {
}
}
}
_lastmodified = _file.lastModified();
}
}
public synchronized BindingEnumeration getVariables()
{
load();
return _namespace.keysAndElements();
}
public synchronized Any getVariable(String name)
{
load();
Any value = _namespace.get(Any.create(name));
if (value == null) {
value = Any.UNDEFINED;
}
if (_copyonget) {
value = value.copy();
}
return value;
}
public synchronized Any setVariable(String name, Any value)
{
load();
if (_copyonset) {
value = value.copy();
}
_namespace.append(name, value);
save(false);
return value;
}
public synchronized Any checkVariable(String name)
{
load();
Any value = _namespace.get(Any.create(name));
if (value != null) {
return value;
} else {
return Any.UNDEFINED;
}
}
public synchronized boolean deleteVariable(String name)
{
load();
boolean deleted = (_namespace.remove(Any.create(name)) != null);
if (deleted) {
save(false);
}
return deleted;
}
}