001: /*
002: * $Id: PersistentFileNamespace.java,v 1.7 2002/09/16 08:05:06 jkl Exp $
003: *
004: * Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
005: *
006: * Use is subject to license terms, as defined in
007: * Anvil Sofware License, Version 1.1. See LICENSE
008: * file, or http://njet.org/license-1.1.txt
009: */
010: package anvil.server.file;
011:
012: import java.io.File;
013: import java.io.InputStream;
014: import java.io.FileInputStream;
015: import java.io.FileOutputStream;
016: import anvil.java.util.BindingEnumeration;
017: import anvil.core.Any;
018: import anvil.core.Array;
019: import anvil.core.Serialization;
020: import anvil.server.PersistentNamespace;
021: import anvil.server.NamespacePreferences;
022: import anvil.server.Zone;
023: import anvil.server.ConfigurationError;
024: import anvil.script.Context;
025:
026: /**
027: * class PersistentFileNamespace
028: *
029: * @author: Jani Lehtimäki
030: */
031: public class PersistentFileNamespace implements PersistentNamespace {
032:
033: protected Zone _zone;
034: protected File _file;
035: protected boolean _copyonget = false;
036: protected boolean _copyonset = false;
037: protected boolean _loaded = false;
038: protected int _modcount = 0;
039: protected int _maxmodcount = 100;
040: protected long _lastmodified = -1;
041: protected String _name = "";
042: protected Array _namespace = new Array();
043:
044: public PersistentFileNamespace() {
045: }
046:
047: public PersistentFileNamespace(Zone zone, String name, File file,
048: boolean copyonget, boolean copyonset, int maxmodcount) {
049:
050: _name = name;
051: _file = file;
052: _zone = zone;
053: _copyonget = copyonget;
054: _copyonset = copyonset;
055: _maxmodcount = maxmodcount;
056: }
057:
058: public String toString() {
059: return "PersistentFileNamespace(" + _name + "@" + _file + ")";
060: }
061:
062: public String getName() {
063: return _name;
064: }
065:
066: public void initialize(Zone zone, NamespacePreferences prefs) {
067: String filename = (String) prefs.getPreference("file");
068: if (filename == null) {
069: throw new ConfigurationError(
070: "PersistentFileNamespace requires existends of property 'file'");
071: }
072: File file = new File(filename);
073: _name = prefs.getName();
074: _file = file;
075: _zone = zone;
076: _copyonget = prefs.getBooleanPreference("copyonget", false);
077: _copyonset = prefs.getBooleanPreference("copyonset", false);
078: _maxmodcount = prefs.getIntPreference("maxmodifications", 1);
079: if (_maxmodcount < 1) {
080: _maxmodcount = 1;
081: }
082: _zone.log().info("Namespace " + this + " initialized");
083: }
084:
085: public synchronized void remove() {
086: _namespace.clear();
087: _file.delete();
088: }
089:
090: public synchronized void commit() {
091: save(true);
092: }
093:
094: public void stop() {
095: save(true);
096: _zone.log().info("Namespace " + this + " stopped");
097: }
098:
099: private void load() {
100: if (_file.exists() && _file.canRead()) {
101: if (!_loaded || (_file.lastModified() > _lastmodified)) {
102: FileInputStream in = null;
103: try {
104: if (_file.length() > 0) {
105: in = new FileInputStream(_file);
106: Any data = Serialization.unserialize(null, in);
107: if (data.isArray()) {
108: _namespace = data.toArray();
109: }
110: } else {
111: _namespace.clear();
112: }
113: } catch (Throwable t) {
114: _zone.log().error(t);
115: } finally {
116: if (in != null) {
117: try {
118: in.close();
119: } catch (Throwable t) {
120: }
121: }
122: }
123: _lastmodified = _file.lastModified();
124: _loaded = true;
125: }
126: }
127: }
128:
129: private void save(boolean forcesave) {
130: _modcount++;
131: if (((_modcount % _maxmodcount) == 0) || forcesave) {
132: FileOutputStream out = null;
133: try {
134: out = new FileOutputStream(_file);
135: Serialization.serialize(null, _namespace, out);
136: } catch (Throwable t) {
137: _zone.log().error(t);
138: } finally {
139: if (out != null) {
140: try {
141: out.close();
142: } catch (Throwable t) {
143: }
144: }
145: }
146: _lastmodified = _file.lastModified();
147: }
148: }
149:
150: public synchronized BindingEnumeration getVariables() {
151: load();
152: return _namespace.keysAndElements();
153: }
154:
155: public synchronized Any getVariable(String name) {
156: load();
157: Any value = _namespace.get(Any.create(name));
158: if (value == null) {
159: value = Any.UNDEFINED;
160: }
161: if (_copyonget) {
162: value = value.copy();
163: }
164: return value;
165: }
166:
167: public synchronized Any setVariable(String name, Any value) {
168: load();
169: if (_copyonset) {
170: value = value.copy();
171: }
172: _namespace.append(name, value);
173: save(false);
174: return value;
175: }
176:
177: public synchronized Any checkVariable(String name) {
178: load();
179: Any value = _namespace.get(Any.create(name));
180: if (value != null) {
181: return value;
182: } else {
183: return Any.UNDEFINED;
184: }
185: }
186:
187: public synchronized boolean deleteVariable(String name) {
188: load();
189: boolean deleted = (_namespace.remove(Any.create(name)) != null);
190: if (deleted) {
191: save(false);
192: }
193: return deleted;
194: }
195:
196: }
|