001 /* 002 * Copyright 2005,2009 Ivan SZKIBA 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.ini4j; 017 018 import org.ini4j.spi.BeanAccess; 019 import org.ini4j.spi.BeanTool; 020 021 import java.util.regex.Matcher; 022 import java.util.regex.Pattern; 023 024 public class OptionMapImpl extends MultiMapImpl<String, String> implements OptionMap 025 { 026 private static final char SUBST_CHAR = '$'; 027 private static final String SYSTEM_PROPERTY_PREFIX = "@prop/"; 028 private static final String ENVIRONMENT_PREFIX = "@env/"; 029 private static final int SYSTEM_PROPERTY_PREFIX_LEN = SYSTEM_PROPERTY_PREFIX.length(); 030 private static final int ENVIRONMENT_PREFIX_LEN = ENVIRONMENT_PREFIX.length(); 031 private static final Pattern EXPRESSION = Pattern.compile("(?<!\\\\)\\$\\{(([^\\[]+)(\\[([0-9]+)\\])?)\\}"); 032 private static final int G_OPTION = 2; 033 private static final int G_INDEX = 4; 034 private BeanAccess _defaultBeanAccess; 035 036 @Override public <T> T as(Class<T> clazz) 037 { 038 return BeanTool.getInstance().proxy(clazz, getDefaultBeanAccess()); 039 } 040 041 @Override public <T> T as(Class<T> clazz, String keyPrefix) 042 { 043 return BeanTool.getInstance().proxy(clazz, newBeanAccess(keyPrefix)); 044 } 045 046 @Override public String fetch(Object key) 047 { 048 int len = length(key); 049 050 return (len == 0) ? null : fetch(key, len - 1); 051 } 052 053 @Override public String fetch(Object key, int index) 054 { 055 String value = get(key, index); 056 057 if ((value != null) && (value.indexOf(SUBST_CHAR) >= 0)) 058 { 059 StringBuilder buffer = new StringBuilder(value); 060 061 resolve(buffer); 062 value = buffer.toString(); 063 } 064 065 return value; 066 } 067 068 @Override public void from(Object bean) 069 { 070 BeanTool.getInstance().inject(getDefaultBeanAccess(), bean); 071 } 072 073 @Override public void from(Object bean, String keyPrefix) 074 { 075 BeanTool.getInstance().inject(newBeanAccess(keyPrefix), bean); 076 } 077 078 @Override public void to(Object bean) 079 { 080 BeanTool.getInstance().inject(bean, getDefaultBeanAccess()); 081 } 082 083 @Override public void to(Object bean, String keyPrefix) 084 { 085 BeanTool.getInstance().inject(bean, newBeanAccess(keyPrefix)); 086 } 087 088 protected synchronized BeanAccess getDefaultBeanAccess() 089 { 090 if (_defaultBeanAccess == null) 091 { 092 _defaultBeanAccess = newBeanAccess(); 093 } 094 095 return _defaultBeanAccess; 096 } 097 098 protected BeanAccess newBeanAccess() 099 { 100 return new Access(); 101 } 102 103 protected BeanAccess newBeanAccess(String propertyNamePrefix) 104 { 105 return new Access(propertyNamePrefix); 106 } 107 108 protected void resolve(StringBuilder buffer) 109 { 110 Matcher m = EXPRESSION.matcher(buffer); 111 112 while (m.find()) 113 { 114 String name = m.group(G_OPTION); 115 int index = (m.group(G_INDEX) == null) ? -1 : Integer.parseInt(m.group(G_INDEX)); 116 String value; 117 118 if (name.startsWith(ENVIRONMENT_PREFIX)) 119 { 120 value = System.getenv(name.substring(ENVIRONMENT_PREFIX_LEN)); 121 } 122 else if (name.startsWith(SYSTEM_PROPERTY_PREFIX)) 123 { 124 value = System.getProperty(name.substring(SYSTEM_PROPERTY_PREFIX_LEN)); 125 } 126 else 127 { 128 value = (index == -1) ? fetch(name) : fetch(name, index); 129 } 130 131 if (value != null) 132 { 133 buffer.replace(m.start(), m.end(), value); 134 m.reset(buffer); 135 } 136 } 137 } 138 139 protected class Access implements BeanAccess 140 { 141 private final String _prefix; 142 143 protected Access() 144 { 145 this(null); 146 } 147 148 protected Access(String prefix) 149 { 150 _prefix = prefix; 151 } 152 153 public void propAdd(String propertyName, String value) 154 { 155 add(transform(propertyName), value); 156 } 157 158 public String propDel(String propertyName) 159 { 160 return remove(transform(propertyName)); 161 } 162 163 public String propGet(String propertyName) 164 { 165 return fetch(transform(propertyName)); 166 } 167 168 public String propGet(String propertyName, int index) 169 { 170 return fetch(transform(propertyName), index); 171 } 172 173 public int propLength(String propertyName) 174 { 175 return length(transform(propertyName)); 176 } 177 178 public String propSet(String propertyName, String value) 179 { 180 return put(transform(propertyName), value); 181 } 182 183 public String propSet(String propertyName, String value, int index) 184 { 185 return put(transform(propertyName), value, index); 186 } 187 188 private String transform(String orig) 189 { 190 return (orig == null) ? null : ((_prefix == null) ? orig : (_prefix + orig)); 191 } 192 } 193 }