001: /*
002: * Copyright (c) 1998-2007 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Sam
028: */
029:
030: package com.caucho.quercus.module;
031:
032: import com.caucho.quercus.env.*;
033: import com.caucho.quercus.Quercus;
034: import com.caucho.util.L10N;
035:
036: import java.util.IdentityHashMap;
037:
038: public class IniDefinition {
039: private L10N L = new L10N(IniDefinition.class);
040:
041: public static final int PHP_INI_USER = 1;
042: public static final int PHP_INI_PERDIR = 2;
043: public static final int PHP_INI_SYSTEM = 4;
044: public static final int PHP_INI_ALL = 7;
045:
046: public static IniDefinition NULL = new Null();
047:
048: private final String _name;
049: private final int _scope;
050: private final Value _deflt;
051: private final Type _type;
052:
053: public enum Type {
054: BOOLEAN, STRING, LONG
055: };
056:
057: public IniDefinition(String name, Type type, Value deflt, int scope) {
058: assert name != null;
059:
060: assert deflt != null;
061:
062: assert scope == PHP_INI_USER || scope == PHP_INI_PERDIR
063: || scope == PHP_INI_SYSTEM || scope == PHP_INI_ALL;
064:
065: _name = name.intern();
066: _type = type;
067: _scope = scope;
068: _deflt = deflt;
069: }
070:
071: /**
072: * Returns the name of the ini definition.
073: */
074: protected String getName() {
075: return _name;
076: }
077:
078: /**
079: * Returns the default value of the ini definition.
080: */
081: protected Value getDefault() {
082: return _deflt;
083: }
084:
085: /**
086: * Returns the scope in which the value of the ini variable can be set.
087: */
088: public int getScope() {
089: return _scope;
090: }
091:
092: /**
093: * Returns true if this definition was added at runtime and not
094: * definied by a module.
095: */
096: public boolean isRuntimeDefinition() {
097: return false;
098: }
099:
100: private BooleanValue toBooleanValue(Value value) {
101: if (value instanceof BooleanValue)
102: return (BooleanValue) value;
103:
104: if (!(value instanceof StringValue))
105: return BooleanValue.create(value.toBoolean());
106:
107: String valueAsString = value.toString().trim();
108:
109: if (valueAsString.length() == 0
110: || valueAsString.equalsIgnoreCase("false")
111: || valueAsString.equalsIgnoreCase("off")
112: || valueAsString.equalsIgnoreCase("0"))
113: return BooleanValue.FALSE;
114: else
115: return BooleanValue.TRUE;
116: }
117:
118: /*
119: private LongValue toLongValue(Value value)
120: {
121: if (value instanceof LongValue)
122: return (LongValue) value;
123: else if (! (value instanceof StringValue))
124: return LongValue.create(value.toLong());
125:
126: String valueAsString = value.toString().trim();
127:
128: if (valueAsString.length() == 0)
129: return LongValue.ZERO;
130:
131: char suffix = valueAsString.charAt(valueAsString.length() - 1);
132:
133: long val = value.toLong();
134:
135: if (suffix == 'G')
136: val = 1024 * 1024 * val;
137: else if (suffix == 'M')
138: val = 1024 * 1024 * val;
139: else if (suffix == 'K')
140: val = 1024 * val;
141:
142: return LongValue.create(val);
143: }
144: */
145:
146: /**
147: * Set the ini value for the given scope.
148: */
149: public void set(Quercus quercus, Value value) {
150: set(quercus.getIniMap(true), PHP_INI_SYSTEM, value);
151: }
152:
153: /**
154: * Set the ini value for the given scope.
155: */
156: public void set(Quercus quercus, String value) {
157: set(quercus.getIniMap(true), PHP_INI_SYSTEM,
158: new StringBuilderValue(value));
159: }
160:
161: /**
162: * Set the ini value for the given scope.
163: */
164: public void set(Env env, Value value) {
165: set(env.getIniMap(true), PHP_INI_USER, value);
166: }
167:
168: /**
169: * Set the ini value for the given scope.
170: */
171: public void set(Env env, String value) {
172: set(env.getIniMap(true), PHP_INI_USER, env.createString(value));
173: }
174:
175: /**
176: * Set the ini value for the given scope.
177: */
178: protected void set(IdentityHashMap<String, Value> map, int scope,
179: Value value) {
180: if (scope == PHP_INI_USER
181: && !(_scope == PHP_INI_USER || _scope == PHP_INI_ALL)) {
182: // do nothing
183: } else if (_type == Type.BOOLEAN) {
184: map.put(_name, toBooleanValue(value));
185: }
186: /* up to modules to interpret values
187: * http://bugs.caucho.com/view.php?id=2095
188: else if (_type == Type.LONG)
189: map.put(_name, toLongValue(value));
190: */
191: else
192: map.put(_name, value);
193: }
194:
195: private Value get(IdentityHashMap<String, Value> envMap,
196: IdentityHashMap<String, Value> quercusMap) {
197: Value value = null;
198:
199: if (envMap != null)
200: value = envMap.get(_name);
201:
202: if (value == null && quercusMap != null)
203: value = quercusMap.get(_name);
204:
205: if (value == null)
206: value = _deflt;
207:
208: if (value == null)
209: value = NullValue.NULL;
210:
211: return value;
212: }
213:
214: /**
215: * Returns the value set for name, or the default from the definition if
216: * it has not been set.
217: */
218: public Value getValue(Quercus quercus) {
219: return get(null, quercus.getIniMap(false));
220: }
221:
222: /**
223: * Returns the value set for name, the first oof the local value set for the
224: * environment, the global configuration value set for quercus, or the default
225: * from the definition.
226: *
227: * @returns the value, or NullValue.NULL.
228: */
229: public Value getValue(Env env) {
230: return get(env.getIniMap(false), env.getQuercus().getIniMap(
231: false));
232: }
233:
234: public StringValue getAsStringValue(Quercus quercus) {
235: return get(null, quercus.getIniMap(false)).toStringValue();
236: }
237:
238: public StringValue getAsStringValue(Env env) {
239: return getValue(env).toStringValue();
240: }
241:
242: /**
243: * @returns the value, null if the value is empty
244: */
245: public String getAsString(Env env) {
246: StringValue value = getAsStringValue(env);
247:
248: return (value.length() == 0) ? null : value.toString();
249: }
250:
251: public boolean getAsBoolean(Quercus quercus) {
252: return getAsBooleanValue(quercus).toBoolean();
253: }
254:
255: public boolean getAsBoolean(Env env) {
256: return getAsBooleanValue(env).toBoolean();
257: }
258:
259: public BooleanValue getAsBooleanValue(Quercus quercus) {
260: return getAsBooleanValue(null, quercus.getIniMap(false));
261: }
262:
263: public BooleanValue getAsBooleanValue(Env env) {
264: return getAsBooleanValue(env.getIniMap(false), env.getQuercus()
265: .getIniMap(false));
266: }
267:
268: private BooleanValue getAsBooleanValue(
269: IdentityHashMap<String, Value> overrideMap,
270: IdentityHashMap<String, Value> iniMap) {
271: Value value = get(overrideMap, iniMap);
272:
273: return toBooleanValue(value);
274: }
275:
276: public LongValue getAsLongValue(Quercus quercus) {
277: return getAsLongValue(null, quercus.getIniMap(false));
278: }
279:
280: public LongValue getAsLongValue(Env env) {
281: return getAsLongValue(env.getIniMap(false), env.getQuercus()
282: .getIniMap(false));
283: }
284:
285: private LongValue getAsLongValue(
286: IdentityHashMap<String, Value> overrideMap,
287: IdentityHashMap<String, Value> iniMap) {
288: Value value = get(overrideMap, iniMap);
289:
290: if (value instanceof LongValue)
291: return (LongValue) value;
292: else if (value instanceof BooleanValue)
293: return value.toBoolean() ? LongValue.ONE : LongValue.ZERO;
294: else
295: return new LongValue(value.toLong());
296: }
297:
298: public long getAsLong(Env env) {
299: return getAsLongValue(env).toLong();
300: }
301:
302: public long getAsLongBytes(Env env, long deflt) {
303: String bytes = getAsString(env);
304:
305: if (bytes == null)
306: return deflt;
307:
308: long value = 0;
309: long sign = 1;
310: int i = 0;
311: int length = bytes.length();
312:
313: if (length == 0)
314: return deflt;
315:
316: if (bytes.charAt(i) == '-') {
317: sign = -1;
318: i++;
319: } else if (bytes.charAt(i) == '+') {
320: i++;
321: }
322:
323: if (length <= i)
324: return deflt;
325:
326: int ch;
327: for (; i < length && (ch = bytes.charAt(i)) >= '0' && ch <= '9'; i++)
328: value = 10 * value + ch - '0';
329:
330: value = sign * value;
331:
332: if (bytes.endsWith("gb") || bytes.endsWith("g")
333: || bytes.endsWith("G")) {
334: return value * 1024L * 1024L * 1024L;
335: } else if (bytes.endsWith("mb") || bytes.endsWith("m")
336: || bytes.endsWith("M")) {
337: return value * 1024L * 1024L;
338: } else if (bytes.endsWith("kb") || bytes.endsWith("k")
339: || bytes.endsWith("K")) {
340: return value * 1024L;
341: } else if (bytes.endsWith("b") || bytes.endsWith("B")) {
342: return value;
343: } else if (value < 0)
344: return value;
345: else {
346: env
347: .warning(L
348: .l(
349: "byte-valued expression '{0}' for ini value '{1}' must have units. '16B' for bytes, '16K' for kilobytes, '16M' for megabytes, '16G' for gigabytes",
350: _name));
351: return deflt;
352: }
353: }
354:
355: static public class Unsupported extends IniDefinition {
356: private L10N L = new L10N(Unsupported.class);
357:
358: public Unsupported(String name, Type type, Value deflt,
359: int scope) {
360: super (name, type, deflt, scope);
361: }
362:
363: @Override
364: public void set(IdentityHashMap<String, Value> map, int scope,
365: Value value) {
366: // php/1a0u
367: // don't send a warning if it's being turned off (for Drupal)
368: // XXX: send notice instead?
369: if (value.eq(getDefault()))
370: return;
371: //Env.getInstance().notice(L.l("ini value `{0}' is not supported", getName()));
372: else
373: Env.getInstance().warning(
374: L.l("ini value `{0}' is not supported",
375: getName()));
376: }
377: }
378:
379: static private class Null extends Unsupported {
380: private L10N L = new L10N(Unsupported.class);
381:
382: public Null() {
383: super ("#null", IniDefinition.Type.STRING, NullValue.NULL,
384: PHP_INI_ALL);
385: }
386:
387: @Override
388: public void set(IdentityHashMap<String, Value> map, int scope,
389: Value value) {
390: if (true)
391: throw new UnsupportedOperationException();
392:
393: Env.getInstance().warning(
394: L.l("ini value `{0}' is not supported", getName()));
395: }
396: }
397:
398: static public class Runtime extends IniDefinition {
399: public Runtime(String name) {
400: super (name, IniDefinition.Type.STRING, NullValue.NULL,
401: IniDefinition.PHP_INI_ALL);
402: }
403:
404: @Override
405: public boolean isRuntimeDefinition() {
406: return true;
407: }
408: }
409:
410: }
|