blob: c3bb7ace35f796bd15e746d1cbac8d8048ae92b1 [file] [log] [blame]
Thomas Vachuskaa8f4e7d2015-01-08 17:31:55 -08001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.net.driver;
17
18import com.google.common.collect.ImmutableMap;
19import org.apache.commons.configuration.ConfigurationException;
20import org.apache.commons.configuration.HierarchicalConfiguration;
21import org.apache.commons.configuration.XMLConfiguration;
22
23import java.io.IOException;
24import java.io.InputStream;
25import java.util.Map;
26
27/**
28 * Utility capable of reading driver configuration XML resources and producing
29 * a device driver provider as a result.
30 * <p>
31 * The drivers stream structure is as follows:
32 * </p>
33 * <pre>
34 * &lt;drivers&gt;
35 * &lt;driver name=“...” [manufacturer="..." hwVersion="..." swVersion="..."]&gt;
36 * &lt;behaviour api="..." impl="..."/&gt;
37 * ...
38 * [&lt;property name=“key”&gt;value&lt;/key&gt;]
39 * ...
40 * &lt;/driver&gt;
41 * ...
42 * &lt;/drivers&gt;
43 * </pre>
44 */
45public class XmlDriverLoader {
46
47 private static final String DRIVERS = "drivers";
48 private static final String DRIVER = "driver";
49
50 private static final String BEHAVIOUR = "behaviour";
51 private static final String PROPERTY = "property";
52
53 private static final String NAME = "[@name]";
54 private static final String MFG = "[@manufacturer]";
55 private static final String HW = "[@hwVersion]";
56 private static final String SW = "[@swVersion]";
57 private static final String API = "[@api]";
58 private static final String IMPL = "[@impl]";
59
60 private final ClassLoader classLoader;
61
62 /**
63 * Creates a new driver loader capable of loading drivers from the supplied
64 * class loader.
65 *
66 * @param classLoader class loader to use
67 */
68 public XmlDriverLoader(ClassLoader classLoader) {
69 this.classLoader = classLoader;
70 }
71
72 /**
73 * Loads the specified drivers resource as an XML stream and parses it to
74 * produce a ready-to-register driver provider.
75 *
76 * @param driversStream stream containing the drivers definitions
77 * @return driver provider
78 * @throws java.io.IOException if issues are encountered reading the stream
79 * or parsing the driver definitions within
80 */
81 public DefaultDriverProvider loadDrivers(InputStream driversStream) throws IOException {
82 try {
83 XMLConfiguration cfg = new XMLConfiguration();
84 cfg.setRootElementName(DRIVERS);
85 cfg.setAttributeSplittingDisabled(true);
86
87 cfg.load(driversStream);
88 return loadDrivers(cfg);
89 } catch (ConfigurationException e) {
90 throw new IOException("Unable to load drivers", e);
91 }
92 }
93
94 /**
95 * Loads a driver provider from the supplied hierarchical configuration.
96 *
97 * @param driversCfg hierarchical configuration containing the drivers definitions
98 * @return driver provider
99 */
100 public DefaultDriverProvider loadDrivers(HierarchicalConfiguration driversCfg) {
101 DefaultDriverProvider provider = new DefaultDriverProvider();
102 for (HierarchicalConfiguration cfg : driversCfg.configurationsAt(DRIVER)) {
103 provider.addDriver(loadDriver(cfg));
104 }
105 return provider;
106 }
107
108 /**
109 * Loads a driver from the supplied hierarchical configuration.
110 *
111 * @param driverCfg hierarchical configuration containing the driver definition
112 * @return driver
113 */
114 public DefaultDriver loadDriver(HierarchicalConfiguration driverCfg) {
115 String name = driverCfg.getString(NAME);
116 String manufacturer = driverCfg.getString(MFG, "");
117 String hwVersion = driverCfg.getString(HW, "");
118 String swVersion = driverCfg.getString(SW, "");
119
120 return new DefaultDriver(name, manufacturer, hwVersion, swVersion,
121 parseBehaviours(driverCfg),
122 parseProperties(driverCfg));
123 }
124
125 // Parses the behaviours section.
126 private Map<Class<? extends Behaviour>, Class<? extends Behaviour>>
127 parseBehaviours(HierarchicalConfiguration driverCfg) {
128 ImmutableMap.Builder<Class<? extends Behaviour>,
129 Class<? extends Behaviour>> behaviours = ImmutableMap.builder();
130 for (HierarchicalConfiguration b : driverCfg.configurationsAt(BEHAVIOUR)) {
131 behaviours.put(getClass(b.getString(API)), getClass(b.getString(IMPL)));
132 }
133 return behaviours.build();
134 }
135
136 // Parses the properties section.
137 private Map<String, String> parseProperties(HierarchicalConfiguration driverCfg) {
138 ImmutableMap.Builder<String, String> properties = ImmutableMap.builder();
139 for (HierarchicalConfiguration b : driverCfg.configurationsAt(PROPERTY)) {
140 properties.put(b.getString(NAME), (String) b.getRootNode().getValue());
141 }
142 return properties.build();
143 }
144
145 @SuppressWarnings("unchecked")
146 private Class<? extends Behaviour> getClass(String className) {
147 try {
148 return (Class<? extends Behaviour>) classLoader.loadClass(className);
149 } catch (ClassNotFoundException e) {
150 throw new IllegalArgumentException("Unable to load class " + className, e);
151 }
152 }
153
154}