Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
src.main.java.com.eva.properties.PropertiesParser Maven / Gradle / Ivy
Go to download
Advanced properties with object factories, references and inheritance.
/*
* $Id: PropertiesParser.java 43 2007-02-27 21:30:21Z max $
*
* Copyright (c) 2006-2007 Maximilian Antoni. All rights reserved.
*
* This software is licensed as described in the file LICENSE.txt, which you
* should have received as part of this distribution. The terms are also
* available at http://www.maxantoni.de/projects/eva-properties/license.txt.
*/
package com.eva.properties;
import java.io.IOException;
import java.io.Reader;
import java.io.StreamTokenizer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* parses property files.
*
* @author Max Antoni
* @version $Revision: 43 $
*/
class PropertiesParser {
private StreamTokenizer st;
private Properties current;
private boolean proxyParent;
private PropertiesParser(Reader inReader, boolean inProxyParent) {
super();
if(inReader == null) {
throw new NullPointerException();
}
st = new StreamTokenizer(inReader);
st.resetSyntax();
st.wordChars('a', 'z');
st.wordChars('A', 'Z');
st.parseNumbers();
st.wordChars(128 + 32, 255);
st.wordChars('_', '_');
st.whitespaceChars(0, ' ');
st.quoteChar('"');
st.quoteChar('\'');
st.ordinaryChar('.');
st.eolIsSignificant(true);
st.slashSlashComments(true);
st.slashStarComments(true);
proxyParent = inProxyParent;
}
static Properties read(Properties inParent, DataSource inDataSource)
throws IOException {
try {
return new PropertiesParser(inDataSource.getReader(), true)
.mapOrList(inParent);
}
catch(IllegalStateException e) {
throw new PropertiesException(e.getMessage());
}
}
static Properties read(DataSource inDataSource, boolean inProxyParent)
throws IOException {
Properties properties;
try {
properties = new PropertiesParser(inDataSource.getReader(),
inProxyParent).mapOrList(null);
}
catch(IllegalStateException e) {
throw new PropertiesException(e.getMessage());
}
if(properties instanceof MapProperties) {
initMap((MapProperties) properties, inDataSource);
}
else {
initList((ListProperties) properties, inDataSource);
}
return properties;
}
private static void initList(ListProperties inoutList,
DataSource inDataSource) {
for(Iterator i = inoutList.iterator(); i.hasNext();) {
Object o = i.next();
if(o instanceof MapProperties) {
initMap((MapProperties) o, inDataSource);
}
}
}
private static void initMap(MapProperties inoutMap,
DataSource inDataSource) {
if(!inoutMap.containsKeyInternal(PropertiesFactory.DATASOURCE_BASE)) {
inoutMap.putInternal(PropertiesFactory.DATASOURCE_BASE, inDataSource
.getDelegateBase());
}
ClassLoader classLoader = inDataSource.getClassLoader();
if(classLoader != null) {
inoutMap.put("classloader", classLoader);
}
}
static Object readObject(Reader inReader, boolean inProxyParent)
throws IOException {
try {
return new PropertiesParser(inReader, inProxyParent).primary(true);
}
catch(IllegalStateException e) {
throw new PropertiesException(e.getMessage());
}
}
static void readMap(MapProperties inoutProperties, Reader inReader,
boolean inProxyParent) throws IOException {
PropertiesParser parser = new PropertiesParser(inReader, inProxyParent);
parser.current = inoutProperties;
try {
parser.map(inoutProperties, StreamTokenizer.TT_EOF);
}
catch(IllegalStateException e) {
throw new PropertiesException(e.getMessage());
}
}
static void readList(ListProperties inoutProperties, Reader inReader,
boolean inProxyParent) throws IOException {
PropertiesParser parser = new PropertiesParser(inReader, inProxyParent);
parser.current = inoutProperties;
parser.list(inoutProperties, StreamTokenizer.TT_EOF);
}
private Properties mapOrList(Properties inParent) throws IOException {
Object primary;
try {
primary = primary(true);
}
catch(IllegalStateException e) {
// Handle non-primary types:
switch(st.ttype) {
case '*':
primary = "*";
st.nextToken();
break;
case ':':
if(!"*".equals(e.getMessage())) {
throw e;
}
primary = "*";
break;
default:
throw e;
}
}
if(st.ttype == ':') {
if(!(primary instanceof String)) {
throw new PropertiesException("String expected, "
+ primary.getClass().getName());
}
MapProperties map = new MapProperties(inParent);
current = map;
map.putInternal((String) primary, primary(true));
map(map, StreamTokenizer.TT_EOF);
return map;
}
ListProperties list = new ListProperties(inParent);
current = list;
if(primary instanceof Properties) {
((Properties) primary).setParent(list);
}
list.add(primary);
if(st.ttype == StreamTokenizer.TT_EOF) {
return current;
}
list(list, StreamTokenizer.TT_EOF);
return list;
}
private String token(int inToken) {
switch (inToken) {
case StreamTokenizer.TT_WORD:
return st.sval;
case '\'':
return '\'' + st.sval + '\'';
case '"':
return '"' + st.sval + '"';
case StreamTokenizer.TT_NUMBER:
return String.valueOf(st.nval);
case StreamTokenizer.TT_EOF:
return "EOF";
case StreamTokenizer.TT_EOL:
return "EOL";
default:
return "" + (char) inToken;
}
}
private String error() {
return token(st.ttype) + " line " + st.lineno();
}
private Number number(double inNumber) throws IOException {
if(st.nextToken() == '.') {
if(st.nextToken() != StreamTokenizer.TT_NUMBER) {
throw new IllegalStateException("Number expected, " + error());
}
st.nextToken();
return Double.valueOf(inNumber + "." + st.nval);
}
if(((long) inNumber) == inNumber) {
return new Long((long) inNumber);
}
return new Double(inNumber);
}
private Object primary(boolean inGet) throws IOException {
int token = inGet ? st.nextToken() : st.ttype;
while(token == StreamTokenizer.TT_EOL) {
token = st.nextToken();
}
switch(token) {
case StreamTokenizer.TT_WORD:
String s = st.sval;
st.nextToken();
if("null".equals(s) || "nil".equals(s)) {
return Null.INSTANCE;
}
if("true".equals(s) || "yes".equals(s) || "on".equals(s)) {
return Boolean.TRUE;
}
if("false".equals(s) || "no".equals(s) || "off".equals(s)) {
return Boolean.FALSE;
}
return s;
case StreamTokenizer.TT_NUMBER:
return number(st.nval);
case '\'':
s = st.sval;
st.nextToken();
if(s.length() == 1) {
return new Character(s.charAt(0));
}
return s.toCharArray();
case '"':
s = st.sval;
st.nextToken();
return s;
case '[':
ListProperties list = new ListProperties(current);
current = list;
list(list, ']');
current = list.getParent();
return list;
case '{':
MapProperties map = new MapProperties(current);
current = map;
map(map, '}');
current = map.getParent();
return map;
case '$':
return reference();
case '.':
return doubleNumber();
case '(':
return switcher();
case '&':
return proxy();
case '*':
return factory();
default:
throw new PropertiesException("Unexpected token, " + error());
}
}
private Factory factory() throws IOException {
List arguments = null;
StringBuffer className = new StringBuffer();
while(true) {
switch (st.nextToken()) {
case StreamTokenizer.TT_WORD:
className.append(st.sval);
break;
case '.':
className.append('.');
break;
case '$':
className.append('$');
break;
case '{':
className.append('{');
break;
case '}':
className.append('}');
break;
case '(':
arguments = list(')');
return new Factory(className.toString(), arguments.toArray());
case ':':
if(className.length() == 0) {
/*
* Happens when the first token in a map properties file is
* a "*" that is meant to be a joker. The exception will be
* catched by mapOrList(...).
*/
throw new IllegalStateException("*");
}
default:
return new Factory(className.toString(), null);
}
}
}
private Proxy proxy() throws IOException, PropertiesException {
Object object = primary(true);
if(object instanceof String) {
return new Proxy(proxyParent ? current : null, (String) object);
}
if(object instanceof Replaceable) {
return new Proxy(proxyParent ? current : null, (Replaceable) object);
}
throw new PropertiesException("String or Replaceable expected, "
+ object.getClass().getName());
}
private Switch switcher() throws IOException {
st.nextToken();
Switch s = new Switch();
while(st.ttype != ')') {
s.add(primary(false));
if(st.ttype != ',' && st.ttype != StreamTokenizer.TT_EOL) {
if(st.ttype == ')') {
break;
}
throw new PropertiesException(") or , or EOL expected, "
+ error());
}
overreadEmptyLines();
}
st.nextToken();
return s;
}
private void overreadEmptyLines() throws IOException {
do {
st.nextToken();
}
while(st.ttype == StreamTokenizer.TT_EOL);
}
private Double doubleNumber() throws IOException {
if(st.nextToken() != StreamTokenizer.TT_NUMBER) {
throw new PropertiesException("Number expected, " + error());
}
return new Double(st.nval);
}
private Reference reference() throws IOException {
if(st.nextToken() != '{') {
throw new PropertiesException("{ expected, " + error());
}
StringBuffer reference = new StringBuffer();
while(st.nextToken() != '}') {
switch(st.ttype) {
case StreamTokenizer.TT_WORD:
reference.append(st.sval);
break;
case StreamTokenizer.TT_NUMBER:
if(((long) st.nval) == st.nval) {
reference.append((long) st.nval);
}
else {
reference.append(st.nval);
}
break;
case '.':
reference.append('.');
break;
case '*':
reference.append('*');
break;
default:
throw new PropertiesException("} expected, " + error());
}
}
st.nextToken();
return new Reference(reference.toString());
}
private void map(MapProperties inoutMap, int inToToken) throws IOException {
overreadEmptyLines();
while(st.ttype != inToToken) {
String key = key();
if(st.nextToken() != ':') {
throw new PropertiesException(": expected, " + error());
}
inoutMap.putInternal(key, primary(true));
if(st.ttype != ',' && st.ttype != StreamTokenizer.TT_EOL) {
if(st.ttype == inToToken) {
break;
}
throw new PropertiesException(token(inToToken) + " expected, "
+ error());
}
overreadEmptyLines();
}
st.nextToken();
}
private List list(int inToToken) throws IOException {
List list = new ArrayList();
list(list, inToToken);
return list;
}
private void list(List inoutList, int inToToken) throws IOException {
overreadEmptyLines();
while(st.ttype != inToToken) {
inoutList.add(primary(false));
if(st.ttype != ',' && st.ttype != StreamTokenizer.TT_EOL) {
if(st.ttype == inToToken) {
break;
}
throw new PropertiesException(token(inToToken)
+ " expected, " + error());
}
overreadEmptyLines();
}
st.nextToken();
}
private String key() throws IOException {
while(st.ttype == StreamTokenizer.TT_EOL) {
st.nextToken();
}
switch (st.ttype) {
case StreamTokenizer.TT_NUMBER:
if(((int) st.nval) == st.nval) {
return String.valueOf((long) st.nval);
}
return String.valueOf(st.nval);
case StreamTokenizer.TT_WORD:
case '"':
case '\'':
return st.sval;
case '*':
return "*";
default:
throw new PropertiesException("Unexpected token, " + error());
}
}
}