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

COVERAGE SUMMARY FOR SOURCE FILE [Domain.java]

nameclass, %method, %block, %line, %
Domain.java100% (1/1)94%  (16/17)90%  (357/395)93%  (77.7/84)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Domain100% (1/1)94%  (16/17)90%  (357/395)93%  (77.7/84)
getServices (): List 0%   (0/1)0%   (0/3)0%   (0/1)
initializeLogging (): void 100% (1/1)69%  (57/83)83%  (17.4/21)
executeBatchFile (CellShell, URI): void 100% (1/1)85%  (23/27)92%  (5.5/6)
stripScope (String): String 100% (1/1)87%  (13/15)93%  (1.9/2)
start (): void 100% (1/1)94%  (49/52)91%  (10/11)
<static initializer> 100% (1/1)100% (4/4)100% (1/1)
Domain (String, ReplaceableProperties): void 100% (1/1)100% (20/20)100% (5/5)
createService (String): ReplaceableProperties 100% (1/1)100% (18/18)100% (4/4)
executePreload (SystemCell): void 100% (1/1)100% (21/21)100% (5/5)
executeService (SystemCell, ReplaceableProperties): void 100% (1/1)100% (26/26)100% (6/6)
getName (): String 100% (1/1)100% (5/5)100% (1/1)
importLocalParameters (CellShell, ReplaceableProperties): void 100% (1/1)100% (29/29)100% (7/7)
importScopedParameters (CellShell, ReplaceableProperties): void 100% (1/1)100% (34/34)100% (6/6)
importUnscopedParameters (SystemCell, ReplaceableProperties): void 100% (1/1)100% (27/27)100% (5/5)
isScoped (String): boolean 100% (1/1)100% (9/9)100% (1/1)
isScoped (String, String): boolean 100% (1/1)100% (19/19)100% (1/1)
properties (): ReplaceableProperties 100% (1/1)100% (3/3)100% (1/1)

1package org.dcache.boot;
2 
3import java.io.IOException;
4import java.io.InputStream;
5import java.io.InputStreamReader;
6import java.io.File;
7import java.net.URI;
8import java.net.URISyntaxException;
9import java.util.ArrayList;
10import java.util.List;
11import java.util.Map;
12 
13import org.dcache.util.DeprecatableProperties;
14import org.dcache.util.NetworkUtils;
15import org.dcache.util.ReplaceableProperties;
16 
17import dmg.cells.nucleus.CellShell;
18import dmg.cells.nucleus.SystemCell;
19import dmg.util.Args;
20import dmg.util.CommandException;
21 
22import org.slf4j.LoggerFactory;
23import org.slf4j.Logger;
24import ch.qos.logback.classic.LoggerContext;
25import ch.qos.logback.classic.joran.JoranConfigurator;
26import ch.qos.logback.core.joran.spi.JoranException;
27import ch.qos.logback.core.util.StatusPrinter;
28 
29/**
30 * Domain encapsulates the configuration of a domain and its
31 * services. Provides the logic for starting a domain.
32 */
33public class Domain
34{
35    private static final String PROPERTY_DOMAIN_NAME = "domain.name";
36    private static final String PROPERTY_DOMAIN_SERVICE = "domain.service";
37    private static final String PROPERTY_DOMAIN_SERVICE_URI = "domain.service.uri";
38    private static final String PROPERTY_DOMAIN_PRELOAD = "domain.preload";
39 
40    private static final String PROPERTY_LOG_CONFIG = "dcache.log.configuration";
41 
42    private static final String SCHEME_FILE = "file";
43    private static final String SUFFIX_PROPERTIES = ".properties";
44    private static final String SUFFIX_XML = ".xml";
45 
46    private static final Logger _log =
47        LoggerFactory.getLogger(SystemCell.class);
48 
49    private final ReplaceableProperties _properties;
50    private final List<ReplaceableProperties> _services;
51 
52    public Domain(String name, ReplaceableProperties defaults)
53    {
54        _properties = new DeprecatableProperties(defaults);
55        _properties.put(PROPERTY_DOMAIN_NAME, name);
56        _services = new ArrayList<ReplaceableProperties>();
57    }
58 
59    public ReplaceableProperties properties()
60    {
61        return _properties;
62    }
63 
64    public ReplaceableProperties createService(String name)
65    {
66        ReplaceableProperties service =
67            new DeprecatableProperties(_properties);
68        service.put(PROPERTY_DOMAIN_SERVICE, name);
69        _services.add(service);
70        return service;
71    }
72 
73    public String getName()
74    {
75        return _properties.getReplacement(PROPERTY_DOMAIN_NAME);
76    }
77 
78    List<ReplaceableProperties> getServices()
79    {
80        return _services;
81    }
82 
83    public void start()
84        throws URISyntaxException, CommandException, IOException
85    {
86        initializeLogging();
87 
88        String domainName = getName();
89        SystemCell systemCell = new SystemCell(domainName);
90        _log.info("Starting " + domainName);
91 
92        importUnscopedParameters(systemCell, _properties);
93        executePreload(systemCell);
94        for (ReplaceableProperties serviceConfig: _services) {
95            executeService(systemCell, serviceConfig);
96        }
97 
98        if (_services.isEmpty()) {
99            _log.warn("No services found. Domain appears to be empty.");
100        }
101    }
102 
103    private void initializeLogging()
104        throws URISyntaxException, IOException
105    {
106        try {
107            String property = _properties.getReplacement(PROPERTY_LOG_CONFIG);
108            if (property == null) return;
109 
110            URI uri = new URI(property);
111            String path = uri.getPath();
112            if (path == null) {
113                throw new URISyntaxException(property, "Path is missing");
114            }
115 
116            if (uri.getScheme() == null || uri.getScheme().equals(SCHEME_FILE)) {
117                File f = new File(path);
118                uri = f.toURI();
119            }
120 
121            LoggerContext loggerContext =
122                (LoggerContext) LoggerFactory.getILoggerFactory();
123            loggerContext.reset();
124            try {
125                JoranConfigurator configurator = new JoranConfigurator();
126                configurator.setContext(loggerContext);
127                configurator.doConfigure(NetworkUtils.toURL(uri));
128            } finally {
129                StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext);
130            }
131        } catch (JoranException e) {
132            throw new IOException("Failed to load log configuration:" + e.getMessage(), e);
133        }
134    }
135 
136    /**
137     * Returns whether a name is scoped.
138     *
139     * A scoped name begins with the name of the scope followed by the
140     * scoping operator, a forward slash.
141     */
142    private boolean isScoped(String name)
143    {
144        return name.indexOf('/') > -1;
145    }
146 
147    /**
148     * Returns whether a name has a particular scope.
149     */
150    private boolean isScoped(String scope, String name)
151    {
152        return scope.length() < name.length() &&
153            name.startsWith(scope) && name.charAt(scope.length()) == '/';
154    }
155 
156    /**
157     * Returns the unscoped name.
158     */
159    private String stripScope(String name)
160    {
161        int pos = name.indexOf('/');
162        return (pos == -1) ? name : name.substring(pos + 1);
163    }
164 
165    /**
166     * Imports unscoped parameters into a SystemCell.
167     */
168    private void importUnscopedParameters(SystemCell cell,
169                                          ReplaceableProperties properties)
170    {
171        Map<String,Object> domainContext = cell.getDomainContext();
172        for (String key: properties.stringPropertyNames()) {
173            if (!isScoped(key)) {
174                domainContext.put(key, properties.getReplacement(key));
175            }
176        }
177    }
178 
179    /**
180     * Imports service scoped parameters into a CellShell.
181     */
182    private void importScopedParameters(CellShell shell,
183                                        ReplaceableProperties properties)
184        throws CommandException
185    {
186        Map<String,Object> environment = shell.environment();
187        String service = properties.getReplacement(PROPERTY_DOMAIN_SERVICE);
188        for (String key: properties.stringPropertyNames()) {
189            if (isScoped(service, key)) {
190                environment.put(stripScope(key), properties.getReplacement(key));
191            }
192        }
193    }
194 
195    /**
196     * Imports service local parameters into a CellShell.
197     */
198    private void importLocalParameters(CellShell shell,
199                                       ReplaceableProperties properties)
200        throws CommandException
201    {
202        Map<String,Object> environment = shell.environment();
203        for (Object o: properties.keySet()) {
204            String key = (String) o;
205            if (!isScoped(key)) {
206                environment.put(key, properties.getReplacement(key));
207            }
208        }
209    }
210 
211    /**
212     * Executes a preload batch script, if defined.
213     */
214    private void executePreload(SystemCell cell)
215        throws URISyntaxException, IOException, CommandException
216    {
217        String preload = _properties.getReplacement(PROPERTY_DOMAIN_PRELOAD);
218        if (preload != null) {
219            CellShell shell = new CellShell(cell.getNucleus());
220            executeBatchFile(shell, new URI(preload));
221        }
222    }
223 
224    /**
225     * Executes the batch file of the service.
226     */
227    private void executeService(SystemCell cell, ReplaceableProperties service)
228        throws URISyntaxException, IOException, CommandException
229    {
230        /* The per service configuration is loaded into the
231         * environment of the CellShell used to execute the batch
232         * file.
233         */
234        CellShell shell = new CellShell(cell.getNucleus());
235        importScopedParameters(shell, service);
236        importLocalParameters(shell, service);
237 
238        URI uri = new URI(service.getReplacement(PROPERTY_DOMAIN_SERVICE_URI));
239        executeBatchFile(shell, uri);
240    }
241 
242    /**
243     * Executes the batch file in the resource.
244     */
245    private void executeBatchFile(CellShell shell, URI resource)
246        throws URISyntaxException, IOException, CommandException
247    {
248        InputStream input = NetworkUtils.toURL(resource).openStream();
249        try {
250            shell.execute(resource.toString(), new InputStreamReader(input),
251                          new Args(""));
252        } finally {
253            input.close();
254        }
255    }
256}

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