view src/samer/core_/util/Properties.java @ 8:5e3cbbf173aa tip

Reorganise some more
author samer
date Fri, 05 Apr 2019 22:41:58 +0100
parents bf79fb79ee13
children
line wrap: on
line source
/*
 *	Properties.java	
 *
 *	Copyright (c) 2001, Samer Abdallah, King's College London.
 *	All rights reserved.
 *
 *	This software is provided AS IS and WITHOUT ANY WARRANTY; 
 *	without even the implied warranty of MERCHANTABILITY or 
 *	FITNESS FOR A PARTICULAR PURPOSE.
 */

package	samer.core.util;
import	samer.core.*;
import	java.io.*;

public class Properties extends Environment
{
	protected java.util.Properties	props;
	protected boolean	writable;

	public Properties(Environment parent) { 
		this(parent,parent.node(),new java.util.Properties());
	}
	public Properties(Environment parent, java.util.Properties pr) {
		this(parent,parent.node(),pr);
	}
	public Properties(Environment parent, Node n) {
		this(parent,n,new java.util.Properties());
	}
	public Properties(Environment parent, Node n, java.util.Properties pr) {
		super(parent,n); props=pr; writable=true;
	}

	public void save(OutputStream out) throws Exception { props.store(out,"properties"); }
	public void load(InputStream in) throws Exception { props.load(in); }
	public void setWritable(boolean f) { writable=f; }
	protected class Property implements Binding
	{
		String	nm;
		String	vl;
		int		sc;

		Property(String n, String v, int s) { 
			nm=n; sc=s;
			vl = v.equals("~default") ? null : v;
		}

		public String	name() { return abs(nm); }		
		public int		score() { return sc; }

		public Object	get() { return vl; }
		public Object	get(Codec c, Object def) { return c.decode(vl==null?def:vl); }
		public void		get(Autocoder obj) { obj.decode(vl); }

		public void		set(Object obj) { props.put(nm,(String)obj); }
		public void		remove() { props.remove(nm); }
	}

	public void store(String name, Autocoder o) {
		if (writable && belongs(name)) props.put(rel(name),o.string());
		else parent.store(name,o);
	}
	public void store(String name, Object o, Codec c) {
		if (writable && belongs(name)) props.put(rel(name),c.string(o));
		else parent.store(name,o,c);
	}

	public Datum datum(String name) 
	{
		Datum local=localFind(rel(name)); // localised name

		if (local.score()>0) { 
			// if match is less than perfect, get parent's best match
			Datum inherited=parent.datum(abs(name));
			if (inherited.score()<local.score()) return inherited;
		}
		return local;
	}

	public Binding binding(String name) 
	{
		Binding local=localFind(rel(name)); // localised name

		if (local.score()>0) { 
			Binding inherited=parent.binding(abs(name));
			if (inherited.score()<local.score()) return inherited;
		}
		return local;
	}

	public Iterator data()
	{
		return new CompoundIterator( new Iterator() {
			java.util.Enumeration enu=props.keys();
			public boolean hasNext() { return enu.hasMoreElements(); }
			public Datum next() {
				String key=(String)enu.nextElement();
				return new Property(key,props.getProperty(key),0);
		} }, parent.data() );
	}

	public Binding localFind(String key) 
	{
		String	val, pname = '.'+key;

		for (int i=0, s=0; i>=0; s++) {
			pname = pname.substring(i+1);
			val=props.getProperty(pname); 
			if (val!=null) return new Property(pname,val,s);
			i = pname.indexOf('.');
		}
		return Null;
	}
}