EMMA Coverage Report (generated Mon Aug 23 17:21:34 CEST 2010)
[all classes][org.dcache.util]

COVERAGE SUMMARY FOR SOURCE FILE [ReplaceableProperties.java]

nameclass, %method, %block, %line, %
ReplaceableProperties.java100% (1/1)67%  (6/9)47%  (88/187)56%  (26.6/48)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ReplaceableProperties100% (1/1)67%  (6/9)47%  (88/187)56%  (26.6/48)
load (InputStream): void 0%   (0/1)0%   (0/18)0%   (0/6)
loadFromXML (InputStream): void 0%   (0/1)0%   (0/18)0%   (0/6)
matchingStringPropertyNames (Collection): Set 0%   (0/1)0%   (0/39)0%   (0/7)
put (Object, Object): Object 100% (1/1)50%  (12/24)67%  (2/3)
load (Reader): void 100% (1/1)78%  (14/18)92%  (5.6/6)
loadFile (File): void 100% (1/1)79%  (15/19)92%  (5.5/6)
getReplacement (String): String 100% (1/1)89%  (31/35)96%  (8.6/9)
ReplaceableProperties (Properties): void 100% (1/1)100% (12/12)100% (4/4)
replaceKeywords (String): String 100% (1/1)100% (4/4)100% (1/1)

1package org.dcache.util;
2 
3import java.io.File;
4import java.io.FileReader;
5import java.io.Reader;
6import java.io.IOException;
7import java.io.InputStream;
8import java.io.PrintStream;
9 
10import java.util.Properties;
11import java.util.Stack;
12import java.util.Set;
13import java.util.HashSet;
14import java.util.NoSuchElementException;
15import java.util.Arrays;
16import java.util.Collection;
17import java.util.InvalidPropertiesFormatException;
18import java.util.regex.Pattern;
19 
20import dmg.util.Replaceable;
21import dmg.util.Formats;
22 
23/**
24 * ReplaceableProperties extends the regular Properties class with
25 * support for ${...} placeholders.
26 *
27 * Besides implementing Replaceable, the class extends the load
28 * methods in such a way that repeated definitions of the same
29 * properties is reported as an error.
30 */
31public class ReplaceableProperties
32    extends Properties
33    implements Replaceable
34{
35    private boolean _loading = false;
36    private Stack<String> _replacementStack = new Stack<String>();
37 
38    public ReplaceableProperties(Properties properties)
39    {
40        super(properties);
41    }
42 
43    /**
44     * @throws IllegalArgumentException during loading if a property
45     * is defined multiple times.
46     */
47    public synchronized void load(Reader reader) throws IOException
48    {
49        _loading = true;
50        try {
51            super.load(reader);
52        } finally {
53            _loading = false;
54        }
55    }
56 
57    /**
58     * @throws IllegalArgumentException during loading if a property
59     * is defined multiple times.
60     */
61    public synchronized void load(InputStream in) throws IOException
62    {
63        _loading = true;
64        try {
65            super.load(in);
66        } finally {
67            _loading = false;
68        }
69    }
70 
71    /**
72     * @throws IllegalArgumentException during loading if a property
73     * is defined multiple times.
74     */
75    public synchronized void loadFromXML(InputStream in)
76        throws IOException, InvalidPropertiesFormatException
77    {
78        _loading = true;
79        try {
80            super.loadFromXML(in);
81        } finally {
82            _loading = false;
83        }
84    }
85 
86    /**
87     * Loads a Java properties file.
88     */
89    public void loadFile(File file)
90        throws IOException
91    {
92        Reader in = new FileReader(file);
93        try {
94            load(in);
95        } finally {
96            in.close();
97        }
98    }
99 
100    /**
101     * @throws IllegalArgumentException during loading if key is
102     * already defined.
103     */
104    public Object put(Object key, Object value)
105    {
106        if (_loading && containsKey(key)) {
107            throw new IllegalArgumentException(String.format("%s is already defined", key));
108        }
109        return super.put(key, value);
110    }
111 
112    /**
113     * Substitutes all placeholders in a string.
114     */
115    public String replaceKeywords(String s)
116    {
117        return Formats.replaceKeywords(s, this);
118    }
119 
120    /**
121     * Returns the value of a property with all placeholders in the
122     * value substituted recursively.
123     */
124    @Override
125    public synchronized String getReplacement(String name)
126        throws NoSuchElementException
127    {
128        String value = getProperty(name);
129        if (value != null) {
130            if (_replacementStack.search(name) == -1) {
131                _replacementStack.push(name);
132                try {
133                    value = replaceKeywords(value);
134                } finally {
135                    _replacementStack.pop();
136                }
137            }
138        }
139        return value;
140    }
141 
142    public synchronized Set<String>
143        matchingStringPropertyNames(Collection<Pattern> patterns)
144    {
145        Set<String> matchingNames = new HashSet<String>();
146        for (String key: stringPropertyNames()) {
147            for (Pattern pattern: patterns) {
148                if (pattern.matcher(key).matches()) {
149                    matchingNames.add(key);
150                    break;
151                }
152            }
153        }
154        return matchingNames;
155    }
156}

[all classes][org.dcache.util]
EMMA 2.0.5312 (C) Vladimir Roubtsov