/** Copyright 2008, 2009 Mark Hooijkaas This file is part of the RelayConnector framework. The RelayConnector framework is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. The RelayConnector framework is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with the RelayConnector framework. If not, see <http://www.gnu.org/licenses/>. */ package org.kisst.props4j; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.LinkedHashMap; import java.util.Map; import org.kisst.util.FileUtil; import org.kisst.util.IndentUtil; import org.kisst.util.IndentUtil.Indentable; import org.kisst.util.StringUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class SimpleProps extends PropsBase implements IndentUtil.Indentable { private static final Logger logger = LoggerFactory.getLogger(SimpleProps.class); //private static final long serialVersionUID = 1L; public final String desc; private final SimpleProps parent; private final String name; private final Map<String, Object> values=new LinkedHashMap<String, Object>(); public String stringValue=null; public SimpleProps() { this(null,null); } public SimpleProps(String name) { this(null,name); } public SimpleProps(File file) { this.parent=null; this.name=null; this.desc="file:"+file.getAbsolutePath(); load(file); } public SimpleProps(SimpleProps parent, String name) { this.parent=parent; if (name!=null && name.lastIndexOf(".")>0) this.name=name.substring(name.lastIndexOf(".")+1); else this.name=name; this.desc=getFullName(); } @Override public Props getParent() { return parent; } @Override public String getLocalName() { return name; } @Override public String getFullName() { if (parent==null) return name; else { String prefix=parent.getFullName(); if (prefix==null) return name; else return prefix+"."+name; } } public SimpleProps shallowClone() { SimpleProps result=new SimpleProps(parent,name); for (String key: keys()) result.put(key, this.get(key)); return result; } @Override public Iterable<String> keys() { return values.keySet(); } @Override public int nrofKeys() { return values.keySet().size();} public SimpleProps put(String key, Object value) { int pos=key.indexOf('.'); if (pos<0) { if (value==null) { if (logger.isInfoEnabled()) logger.info("removing {}",getFullName()+"."+key); values.remove(key); } else { if (logger.isInfoEnabled()) logger.info("put {} = {}",getFullName()+"."+key,value); Object old=values.get(key); if (old instanceof SimpleProps && value instanceof String) ((SimpleProps) old).stringValue=(String) value; else values.put(key, value); } return this; } String keystart=key.substring(0,pos); String keyremainder=key.substring(pos+1); Object o=values.get(keystart); if (o==null || o instanceof String) { SimpleProps props=new SimpleProps(this,keystart); values.put(keystart, props); props.put(keyremainder, value); if (o instanceof String) props.stringValue= (String) o; } else if (o instanceof SimpleProps) ((SimpleProps)o).put(keyremainder, value); else throw new RuntimeException("key "+getFullName()+"."+key+" already has value "+o+" when adding subkey "+keyremainder); return this; } // TODO: code duplication with function above SimpleProps getParentForKeyWithCreate(String key) { int pos=key.indexOf('.'); if (pos<0) return this; String keystart=key.substring(0,pos); String keyremainder=key.substring(pos+1); Object o=values.get(keystart); if (o==null || o instanceof String) { SimpleProps props=new SimpleProps(this,keystart); values.put(keystart, props); if (o instanceof String) props.stringValue= (String) o; return props.getParentForKeyWithCreate(keyremainder); } else if (o instanceof SimpleProps) return ((SimpleProps)o).getParentForKeyWithCreate(keyremainder); else throw new RuntimeException("key "+getFullName()+"."+key+" already has value "+o+" when adding subkey "+keyremainder); } public Object get(String key, Object defaultValue) { logger.debug("getting {}",key); int pos=key.indexOf('.'); if (pos<0) { Object result=values.get(key); if (logger.isInfoEnabled()) logger.info("returned prop {} with value {}",getFullName()+"."+key,result); if (result==null) return defaultValue; else return result; } String keystart=key.substring(0,pos); String keyremainder=key.substring(pos+1); Object o=values.get(keystart); if (o==null) return defaultValue; else if (o instanceof SimpleProps) return ((SimpleProps)o).get(keyremainder,defaultValue); else return defaultValue; } public void load(String filename) { load(new File(filename)); } public void load(File file) { InputStreamReader f = new InputStreamReader(FileUtil.open(file)); try { new Parser(f, file).fillMap(this); } finally { try { f.close(); } catch (IOException e) { throw new RuntimeException(e); } } } public void read(InputStream inp) { new Parser(inp).fillMap(this);} public String toString() { return "SimpleProps("+this.desc+")"; } public String toIndentedString() { return toIndentedString(""); } public String toIndentedString(String indent) { StringBuilder result=new StringBuilder("{\n"); for (String key: values.keySet()) { result.append(indent+"\t"+key+": "); Object o=values.get(key); if (o instanceof Indentable) result.append(((Indentable)o).toIndentedString(indent+"\t")); else if (o instanceof String) result.append(StringUtil.doubleQuotedString((String)o)+";"); else if (o instanceof File) result.append("@file("+o.toString()+")"); else result.append(o.toString()); result.append("\n"); } result.append(indent+"}"); return result.toString(); } public String toPropertiesString() { StringBuilder result=new StringBuilder(); for (String key: values.keySet()) { Object o=values.get(key); if (o instanceof SimpleProps) { result.append(((SimpleProps)o).toPropertiesString()); continue; } result.append(getFullName()+"."+key+"="); if (o instanceof String) result.append(StringUtil.doubleQuotedString((String)o)+"\n"); else if (o instanceof File) result.append("@file("+o.toString()+")\n"); else result.append(o.toString()+"\n"); } return result.toString(); } }