1f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project/* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved.
2f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project *
3f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * This program and the accompanying materials are made available under
4f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * the terms of the Common Public License v1.0 which accompanies this distribution,
5f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * and is available at http://www.eclipse.org/legal/cpl-v10.html
6f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project *
7f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * $Id: Property.java,v 1.1.1.1.2.4 2004/07/16 23:32:04 vlad_r Exp $
8f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project */
9f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectpackage com.vladium.util;
10f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
11f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.io.BufferedInputStream;
12f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.io.File;
13f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.io.FileInputStream;
14f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.io.IOException;
15f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.io.InputStream;
16f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.util.Enumeration;
17f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.util.Hashtable;
18f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.util.Iterator;
19f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.util.Map;
20f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.util.Properties;
21f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
22f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project/*
23f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * NOTE: to avoid certain build problems, this class should use only
24f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * core Java APIs and not any app infrastructure.
25f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project */
26f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
27f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// ----------------------------------------------------------------------------
28f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project/**
29f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * @author Vlad Roubtsov, (C) 2003
30f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project */
31f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectpublic
32f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectabstract class Property
33f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project{
34f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // public: ................................................................
35f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
36f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
37f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public static boolean toBoolean (final String value)
38f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
39f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (value == null)
40f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return false;
41f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        else
42f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return value.startsWith ("t") || value.startsWith ("y");
43f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
44f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
45f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
46f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    /**
47f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * NOTE: this does not guarantee that the result will be mutatable
48f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * independently from 'overrides' or 'base', so this method
49f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * should be used for read-only property only
50f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
51f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @param overrides [null is equivalent to empty]
52f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @param base [null is equivalent to empty]
53f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
54f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @return [never null, could be empty]
55f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     */
56f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public static Properties combine (final Properties overrides, final Properties base)
57f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
58f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // note: no defensive copies here
59f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
60f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (base == null)
61f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
62f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (overrides == null)
63f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                return new XProperties ();
64f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            else
65f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                return overrides;
66f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
67f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
68f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // [assertion: base != null]
69f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
70f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (overrides == null) return base;
71f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
72f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // [assertion: both 'overrides' and 'base' are not null]
73f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
74f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        final Properties result = new XProperties (base);
75f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
76f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // note: must use propertyNames() because that is the only method that recurses
77f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // into possible bases inside 'overrides'
78f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
79f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        for (Enumeration overrideNames = overrides.propertyNames (); overrideNames.hasMoreElements (); )
80f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
81f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final String n = (String) overrideNames.nextElement ();
82f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final String v = overrides.getProperty (n);
83f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
84f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            result.setProperty (n, v);
85f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
86f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
87f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        return result;
88f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
89f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
90f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    /**
91f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * Creates a set of properties for an application with a given namespace.
92f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * This method is not property aliasing-aware.
93f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
94f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @param namespace application namespace [may not be null]
95f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @param loader classloader to use for any classloader resource lookups
96f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * [null is equivalent to the applicaton classloader]
97f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @return application properties [never null, a new instance is created
98f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * on each invocation]
99f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     */
100f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public static Properties getAppProperties (final String namespace, final ClassLoader loader)
101f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
102f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (namespace == null)
103f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            throw new IllegalArgumentException ("null properties: appNameLC");
104f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
105f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        final Properties appDefaults = Property.getProperties (namespace + "_default.properties", loader);
106f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        final Properties systemFileOverrides;
107f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
108f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final String fileName = Property.getSystemProperty (namespace + ".properties");
109f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final File file = fileName != null
110f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                ? new File (fileName)
111f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                : null;
112f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
113f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            systemFileOverrides = Property.getLazyPropertiesFromFile (file);
114f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
115f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        final Properties systemOverrides = Property.getSystemProperties (namespace);
116f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        final Properties resOverrides = Property.getProperties (namespace + ".properties", loader);
117f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
118f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        return combine (resOverrides,
119f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project               combine (systemOverrides,
120f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project               combine (systemFileOverrides,
121f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        appDefaults)));
122f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
123f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
124f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public static Properties getSystemProperties (final String systemPrefix)
125f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
126f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // note: this method is not synchronized on purpose
127f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
128f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        Properties result = s_systemProperties;
129f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (result == null)
130f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
131f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            result = new SystemPropertyLookup (systemPrefix);
132f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
133f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            s_systemProperties = result;
134f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return result;
135f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
136f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
137f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        return result;
138f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
139f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
140f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public static Properties getSystemPropertyRedirects (final Map systemRedirects)
141f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
142f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // note: this method is not synchronized on purpose
143f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
144f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        Properties result = s_systemRedirects;
145f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (result == null)
146f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
147f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            result = new SystemRedirectsLookup (systemRedirects);
148f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
149f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            s_systemRedirects = result;
150f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return result;
151f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
152f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
153f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        return result;
154f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
155f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
156f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
157f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public static String getSystemFingerprint ()
158f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
159f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // [not synchronized intentionally]
160f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
161f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (s_systemFingerprint != null)
162f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return s_systemFingerprint;
163f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        else
164f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
165f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final StringBuffer s = new StringBuffer ();
166f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final char delimiter = ':';
167f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
168f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            s.append (getSystemProperty ("java.vm.name", ""));
169f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            s.append (delimiter);
170f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            s.append (getSystemProperty ("java.vm.version", ""));
171f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            s.append (delimiter);
172f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            s.append (getSystemProperty ("java.vm.vendor", ""));
173f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            s.append (delimiter);
174f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            s.append (getSystemProperty ("os.name", ""));
175f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            s.append (delimiter);
176f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            s.append (getSystemProperty ("os.version", ""));
177f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            s.append (delimiter);
178f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            s.append (getSystemProperty ("os.arch", ""));
179f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
180f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            s_systemFingerprint = s.toString ();
181f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return s_systemFingerprint;
182f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
183f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
184f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
185f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public static String getSystemProperty (final String key)
186f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
187f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        try
188f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
189f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return System.getProperty (key);
190f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
191f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        catch (SecurityException se)
192f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
193f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return null;
194f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
195f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
196f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
197f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public static String getSystemProperty (final String key, final String def)
198f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
199f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        try
200f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
201f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return System.getProperty (key, def);
202f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
203f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        catch (SecurityException se)
204f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
205f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return def;
206f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
207f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
208f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
209f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    /**
210f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * does not throw
211f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
212f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @param name
213f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @return
214f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     */
215f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public static Properties getProperties (final String name)
216f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
217f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        Properties result = null;
218f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
219f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        InputStream in = null;
220f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        try
221f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
222f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            in = ResourceLoader.getResourceAsStream (name);
223f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (in != null)
224f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
225f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                result = new XProperties ();
226f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                result.load (in);
227f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
228f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
229f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        catch (Throwable t)
230f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
231f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            result = null;
232f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
233f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        finally
234f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
235f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (in != null) try { in.close (); } catch (Throwable ignore) {}
236f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            in = null;
237f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
238f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
239f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        return result;
240f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
241f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
242f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    /**
243f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * does not throw
244f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
245f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @param name
246f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @param loader
247f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @return
248f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     */
249f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public static Properties getProperties (final String name, final ClassLoader loader)
250f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
251f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        Properties result = null;
252f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
253f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        InputStream in = null;
254f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        try
255f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
256f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            in = ResourceLoader.getResourceAsStream (name, loader);
257f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (in != null)
258f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
259f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                result = new XProperties ();
260f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                result.load (in);
261f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
262f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
263f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        catch (Throwable t)
264f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
265f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            result = null;
266f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
267f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        finally
268f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
269f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (in != null) try { in.close (); } catch (Throwable ignore) {}
270f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            in = null;
271f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
272f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
273f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        return result;
274f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
275f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
276f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    /**
277f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * Loads 'file' as a .properties file.
278f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
279f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @param file [may not be null]
280f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @return read properties [never null]
281f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @throws IOException on any file I/O errors
282f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     */
283f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public static Properties getPropertiesFromFile (final File file)
284f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        throws IOException
285f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
286f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (file == null)
287f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            throw new IllegalArgumentException ("null input: file");
288f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
289f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        Properties result = null;
290f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
291f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        InputStream in = null;
292f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        try
293f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
294f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            in = new BufferedInputStream (new FileInputStream (file), 8 * 1024);
295f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
296f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            result = new XProperties ();
297f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            result.load (in);
298f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
299f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        finally
300f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
301f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (in != null) try { in.close (); } catch (Throwable ignore) {}
302f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            in = null;
303f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
304f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
305f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        return result;
306f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
307f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
308f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    /**
309f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * Returns a lazy property implementation that will read 'load' as a .properties
310f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * file on first use. If there are any file I/O errors when reading the file,
311f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * they will be thrown as runtime exceptions (also on first use).
312f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
313f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @param file [can be null, which results in an empty property set returned]
314f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @return [never null]
315f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     */
316f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public static Properties getLazyPropertiesFromFile (final File file)
317f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
318f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        return new FilePropertyLookup (file);
319f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
320f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
321f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // protected: .............................................................
322f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
323f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // package: ...............................................................
324f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
325f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // private: ...............................................................
326f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
327f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
328f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private static final class FilePropertyLookup extends XProperties
329f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
330f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // note: due to incredibly stupid coding in java.util.Properties
331f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // (getProperty() uses a non-virtual call to get(), while propertyNames()
332f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // uses a virtual call to the same instead of delegating to getProperty())
333f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // I must override both methods below
334f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
335f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public String getProperty (final String key)
336f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
337f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            faultContents ();
338f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
339f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return m_contents.getProperty (key);
340f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
341f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
342f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public Object get (final Object key)
343f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
344f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            faultContents ();
345f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
346f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return m_contents.get (key);
347f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
348f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
349f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        /*
350f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project         * Overrides Properties.keys () [this is used for debug logging only]
351f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project         */
352f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public Enumeration keys ()
353f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
354f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            faultContents ();
355f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
356f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return m_contents.keys ();
357f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
358f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
359f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
360f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        /**
361f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project         * Creates a lazy property lookup based on 'src' contents.
362f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project         *
363f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project         * @param src [null will result in empty property set created]
364f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project         */
365f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        FilePropertyLookup (final File src)
366f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
367f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_src = src;
368f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
369f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
370f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        /*
371f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project         * @throws RuntimeException on file I/O failures.
372f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project         */
373f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        private synchronized void faultContents ()
374f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
375f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            Properties contents = m_contents;
376f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if ((contents == null) && (m_src != null))
377f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
378f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                try
379f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
380f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    contents = getPropertiesFromFile (m_src);
381f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
382f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                catch (RuntimeException re)
383f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
384f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    throw re; // re-throw;
385f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
386f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                catch (Exception e)
387f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
388f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    throw new RuntimeException ("exception while processing properties file [" + m_src.getAbsolutePath () + "]: " + e);
389f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
390f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
391f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
392f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (contents == null)
393f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
394f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                contents = new XProperties (); // non-null marker
395f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
396f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
397f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_contents = contents;
398f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
399f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
400f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
401f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        private final File m_src; // can be null
402f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        private Properties m_contents; // non-null after faultContents()
403f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
404f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    } // end of nested class
405f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
406f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
407f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private static final class SystemPropertyLookup extends XProperties
408f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
409f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // note: due to incredibly stupid coding in java.util.Properties
410f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // (getProperty() uses a non-virtual call to get(), while propertyNames()
411f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // uses a virtual call to the same instead of delegating to getProperty())
412f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // I must override both methods below
413f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
414f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public String getProperty (final String key)
415f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
416f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return (String) get (key);
417f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
418f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
419f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public Object get (final Object key)
420f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
421f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (! (key instanceof String)) return null;
422f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
423f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            String result = (String) super.get (key);
424f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (result != null) return result;
425f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
426f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (m_systemPrefix != null)
427f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
428f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                result = getSystemProperty (m_systemPrefix.concat ((String) key), null);
429f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
430f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                if (result != null) return result;
431f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
432f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
433f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return result;
434f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
435f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
436f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        /*
437f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project         * Overrides Properties.keys () [this is used for debug logging only]
438f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project         */
439f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public synchronized Enumeration keys ()
440f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
441f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final Hashtable _propertyNames = new Hashtable ();
442f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
443f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (m_systemPrefix != null)
444f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
445f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                try
446f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
447f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    final int systemPrefixLength = m_systemPrefix.length ();
448f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
449f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    for (Enumeration e = System.getProperties ().propertyNames ();
450f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                         e.hasMoreElements (); )
451f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    {
452f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        final String n = (String) e.nextElement ();
453f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
454f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        if (n.startsWith (m_systemPrefix))
455f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        {
456f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                            final String yn = n.substring (systemPrefixLength);
457f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
458f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                            _propertyNames.put (yn, yn);
459f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        }
460f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    }
461f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
462f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                catch (SecurityException ignore)
463f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
464f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    ignore.printStackTrace (System.out);
465f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
466f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    // continue
467f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
468f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
469f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
470f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return _propertyNames.keys ();
471f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
472f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
473f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
474f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        SystemPropertyLookup (String systemPrefix)
475f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
476f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if ((systemPrefix != null) && ! systemPrefix.endsWith ("."))
477f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                systemPrefix = systemPrefix.concat (".");
478f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
479f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_systemPrefix = systemPrefix;
480f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
481f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
482f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
483f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        private final String m_systemPrefix; // can be null [if not null, normalized to end with "."]
484f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
485f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    } // end of nested class
486f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
487f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
488f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private static final class SystemRedirectsLookup extends XProperties
489f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
490f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // note: due to incredibly stupid coding in java.util.Properties
491f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // (getProperty() uses a non-virtual call to get(), while propertyNames()
492f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // uses a virtual call to the same instead of delegating to getProperty())
493f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // I must override both methods below
494f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
495f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public String getProperty (final String key)
496f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
497f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return (String) get (key);
498f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
499f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
500f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public Object get (final Object key)
501f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
502f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (! (key instanceof String)) return null;
503f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
504f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            String result = (String) super.get (key);
505f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (result != null) return result;
506f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
507f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (m_systemRedirects != null)
508f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
509f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                final String redirect = (String) m_systemRedirects.get (key);
510f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
511f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                if (redirect != null)
512f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
513f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    result = getSystemProperty (redirect, null);
514f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    if (result != null) return result;
515f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
516f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
517f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
518f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return result;
519f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
520f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
521f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        /*
522f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project         * Overrides Properties.keys () [this is used for debug logging only]
523f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project         */
524f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public synchronized Enumeration keys ()
525f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
526f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            final Hashtable _propertyNames = new Hashtable ();
527f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
528f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (m_systemRedirects != null)
529f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
530f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                for (Iterator i = m_systemRedirects.keySet ().iterator ();
531f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                     i.hasNext (); )
532f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
533f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    final Object key = i.next ();
534f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    if (key != null) _propertyNames.put (key , key);
535f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
536f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
537f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
538f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return _propertyNames.keys ();
539f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
540f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
541f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
542f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        SystemRedirectsLookup (final Map systemRedirects)
543f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
544f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            m_systemRedirects = systemRedirects; // note: no defensive copy
545f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
546f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
547f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
548f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        private final Map m_systemRedirects; // can be null
549f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
550f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    } // end of nested class
551f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
552f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
553f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private static String s_systemFingerprint;
554f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private static Properties s_systemProperties, s_systemRedirects;
555f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
556f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project} // end of class
557f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// ----------------------------------------------------------------------------