Adding device driver inheritance mechanism.

Change-Id: I9c883d32ce0c39f961eddd5c4624dc23f794fe4d
diff --git a/core/api/src/test/java/org/onosproject/net/driver/DefaultDriverDataTest.java b/core/api/src/test/java/org/onosproject/net/driver/DefaultDriverDataTest.java
index bf4ad52..006957d 100644
--- a/core/api/src/test/java/org/onosproject/net/driver/DefaultDriverDataTest.java
+++ b/core/api/src/test/java/org/onosproject/net/driver/DefaultDriverDataTest.java
@@ -28,7 +28,7 @@
 
     @Before
     public void setUp() {
-        ddc = new DefaultDriver("foo.bar", "Circus", "lux", "1.2a",
+        ddc = new DefaultDriver("foo.bar", null, "Circus", "lux", "1.2a",
                                 ImmutableMap.of(TestBehaviour.class,
                                                 TestBehaviourImpl.class),
                                 ImmutableMap.of("foo", "bar"));
diff --git a/core/api/src/test/java/org/onosproject/net/driver/DefaultDriverHandlerTest.java b/core/api/src/test/java/org/onosproject/net/driver/DefaultDriverHandlerTest.java
index e9a6165..08a508c 100644
--- a/core/api/src/test/java/org/onosproject/net/driver/DefaultDriverHandlerTest.java
+++ b/core/api/src/test/java/org/onosproject/net/driver/DefaultDriverHandlerTest.java
@@ -30,7 +30,7 @@
 
     @Before
     public void setUp() {
-        ddc = new DefaultDriver("foo.bar", "Circus", "lux", "1.2a",
+        ddc = new DefaultDriver("foo.bar", null, "Circus", "lux", "1.2a",
                                 ImmutableMap.of(TestBehaviour.class,
                                                 TestBehaviourImpl.class,
                                                 TestBehaviourTwo.class,
diff --git a/core/api/src/test/java/org/onosproject/net/driver/DefaultDriverProviderTest.java b/core/api/src/test/java/org/onosproject/net/driver/DefaultDriverProviderTest.java
index adfa486..4568fd9 100644
--- a/core/api/src/test/java/org/onosproject/net/driver/DefaultDriverProviderTest.java
+++ b/core/api/src/test/java/org/onosproject/net/driver/DefaultDriverProviderTest.java
@@ -28,15 +28,15 @@
     @Test
     public void basics() {
         DefaultDriverProvider ddp = new DefaultDriverProvider();
-        DefaultDriver one = new DefaultDriver("foo.bar", "Circus", "lux", "1.2a",
+        DefaultDriver one = new DefaultDriver("foo.bar", null, "Circus", "lux", "1.2a",
                                               ImmutableMap.of(TestBehaviour.class,
                                                               TestBehaviourImpl.class),
                                               ImmutableMap.of("foo", "bar"));
-        DefaultDriver two = new DefaultDriver("foo.bar", "", "", "",
+        DefaultDriver two = new DefaultDriver("foo.bar", null, "", "", "",
                                               ImmutableMap.of(TestBehaviourTwo.class,
                                                               TestBehaviourTwoImpl.class),
                                               ImmutableMap.of("goo", "wee"));
-        DefaultDriver three = new DefaultDriver("goo.foo", "BigTop", "better", "2.2",
+        DefaultDriver three = new DefaultDriver("goo.foo", null, "BigTop", "better", "2.2",
                                                 ImmutableMap.of(TestBehaviourTwo.class,
                                                                 TestBehaviourTwoImpl.class),
                                                 ImmutableMap.of("goo", "gee"));
diff --git a/core/api/src/test/java/org/onosproject/net/driver/DefaultDriverTest.java b/core/api/src/test/java/org/onosproject/net/driver/DefaultDriverTest.java
index 204eb3b..17af6c7 100644
--- a/core/api/src/test/java/org/onosproject/net/driver/DefaultDriverTest.java
+++ b/core/api/src/test/java/org/onosproject/net/driver/DefaultDriverTest.java
@@ -25,18 +25,33 @@
 
     @Test
     public void basics() {
-        DefaultDriver ddc = new DefaultDriver("foo.bar", "Circus", "lux", "1.2a",
+        DefaultDriver ddp = new DefaultDriver("foo.base", null, "Circus", "lux", "1.2a",
                                               ImmutableMap.of(TestBehaviour.class,
-                                                              TestBehaviourImpl.class),
+                                                              TestBehaviourImpl.class,
+                                                              TestBehaviourTwo.class,
+                                                              TestBehaviourTwoImpl.class),
+                                              ImmutableMap.of("foo", "bar"));
+
+        DefaultDriver ddc = new DefaultDriver("foo.bar", ddp, "Circus", "lux", "1.2a",
+                                              ImmutableMap.of(),
                                               ImmutableMap.of("foo", "bar"));
         assertEquals("incorrect name", "foo.bar", ddc.name());
+        assertEquals("incorrect parent", ddp, ddc.parent());
         assertEquals("incorrect mfr", "Circus", ddc.manufacturer());
         assertEquals("incorrect hw", "lux", ddc.hwVersion());
         assertEquals("incorrect sw", "1.2a", ddc.swVersion());
 
-        assertEquals("incorrect behaviour count", 1, ddc.behaviours().size());
+        assertEquals("incorrect behaviour count", 2, ddp.behaviours().size());
+        assertEquals("incorrect behaviour count", 0, ddc.behaviours().size());
         assertTrue("incorrect behaviour", ddc.hasBehaviour(TestBehaviour.class));
 
+        Behaviour b1 = ddc.createBehaviour(new DefaultDriverData(ddc), TestBehaviour.class);
+        assertTrue("incorrect behaviour class", b1 instanceof TestBehaviourImpl);
+
+        Behaviour b2 = ddc.createBehaviour(new DefaultDriverHandler(new DefaultDriverData(ddc)),
+                                           TestBehaviourTwo.class);
+        assertTrue("incorrect behaviour class", b2 instanceof TestBehaviourTwoImpl);
+
         assertEquals("incorrect property count", 1, ddc.properties().size());
         assertEquals("incorrect key count", 1, ddc.keys().size());
         assertEquals("incorrect property", "bar", ddc.value("foo"));
@@ -46,12 +61,12 @@
 
     @Test
     public void merge() {
-        DefaultDriver one = new DefaultDriver("foo.bar", "Circus", "lux", "1.2a",
+        DefaultDriver one = new DefaultDriver("foo.bar", null, "Circus", "lux", "1.2a",
                                               ImmutableMap.of(TestBehaviour.class,
                                                               TestBehaviourImpl.class),
                                               ImmutableMap.of("foo", "bar"));
         Driver ddc =
-                one.merge(new DefaultDriver("foo.bar", "", "", "",
+                one.merge(new DefaultDriver("foo.bar", null, "", "", "",
                                             ImmutableMap.of(TestBehaviourTwo.class,
                                                             TestBehaviourTwoImpl.class),
                                             ImmutableMap.of("goo", "wee")));
diff --git a/core/api/src/test/java/org/onosproject/net/driver/XmlDriverLoaderTest.java b/core/api/src/test/java/org/onosproject/net/driver/XmlDriverLoaderTest.java
index 0d5dc6f..ea77a50 100644
--- a/core/api/src/test/java/org/onosproject/net/driver/XmlDriverLoaderTest.java
+++ b/core/api/src/test/java/org/onosproject/net/driver/XmlDriverLoaderTest.java
@@ -19,6 +19,7 @@
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Iterator;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
@@ -32,17 +33,22 @@
     public void basics() throws IOException {
         XmlDriverLoader loader = new XmlDriverLoader(getClass().getClassLoader());
         InputStream stream = getClass().getResourceAsStream("drivers.1.xml");
-        DriverProvider provider = loader.loadDrivers(stream);
+        DriverProvider provider = loader.loadDrivers(stream, null);
         System.out.println(provider);
-        assertEquals("incorrect driver count", 1, provider.getDrivers().size());
+        assertEquals("incorrect driver count", 2, provider.getDrivers().size());
 
-        Driver driver = provider.getDrivers().iterator().next();
+        Iterator<Driver> iterator = provider.getDrivers().iterator();
+        Driver driver = iterator.next();
+        if (!driver.name().equals("foo.1")) {
+            driver = iterator.next();
+        }
+
         assertEquals("incorrect driver name", "foo.1", driver.name());
         assertEquals("incorrect driver mfg", "Circus", driver.manufacturer());
         assertEquals("incorrect driver hw", "1.2a", driver.hwVersion());
         assertEquals("incorrect driver sw", "2.2", driver.swVersion());
 
-        assertEquals("incorrect driver behaviours", 2, driver.behaviours().size());
+        assertEquals("incorrect driver behaviours", 1, driver.behaviours().size());
         assertTrue("incorrect driver behaviour", driver.hasBehaviour(TestBehaviour.class));
 
         assertEquals("incorrect driver properties", 2, driver.properties().size());
@@ -52,20 +58,20 @@
     @Test(expected = IOException.class)
     public void badXML() throws IOException {
         XmlDriverLoader loader = new XmlDriverLoader(getClass().getClassLoader());
-        loader.loadDrivers(getClass().getResourceAsStream("drivers.bad.xml"));
+        loader.loadDrivers(getClass().getResourceAsStream("drivers.bad.xml"), null);
     }
 
     @Test(expected = IllegalArgumentException.class)
     public void noClass() throws IOException {
         XmlDriverLoader loader = new XmlDriverLoader(getClass().getClassLoader());
-        loader.loadDrivers(getClass().getResourceAsStream("drivers.noclass.xml"));
+        loader.loadDrivers(getClass().getResourceAsStream("drivers.noclass.xml"), null);
     }
 
     @Test(expected = IllegalArgumentException.class)
     public void noConstructor() throws IOException {
         XmlDriverLoader loader = new XmlDriverLoader(getClass().getClassLoader());
         InputStream stream = getClass().getResourceAsStream("drivers.noconstructor.xml");
-        DriverProvider provider = loader.loadDrivers(stream);
+        DriverProvider provider = loader.loadDrivers(stream, null);
         Driver driver = provider.getDrivers().iterator().next();
         driver.createBehaviour(new DefaultDriverData(driver), TestBehaviour.class);
     }
diff --git a/core/api/src/test/resources/org/onosproject/net/driver/drivers.1.xml b/core/api/src/test/resources/org/onosproject/net/driver/drivers.1.xml
index 24b4cf8..e449045 100644
--- a/core/api/src/test/resources/org/onosproject/net/driver/drivers.1.xml
+++ b/core/api/src/test/resources/org/onosproject/net/driver/drivers.1.xml
@@ -15,12 +15,15 @@
   ~ limitations under the License.
   -->
 <drivers>
-    <driver name="foo.1" manufacturer="Circus" hwVersion="1.2a" swVersion="2.2">
+    <driver name="foo.0" manufacturer="Circus" hwVersion="1.2" swVersion="2.0">
+        <behaviour api="org.onosproject.net.driver.TestBehaviour"
+                   impl="org.onosproject.net.driver.TestBehaviourImpl"/>
+    </driver>
+
+    <driver name="foo.1" extends="foo.0" manufacturer="Circus" hwVersion="1.2a" swVersion="2.2">
         <fingerprint>ding</fingerprint>
         <fingerprint>bat</fingerprint>
 
-        <behaviour api="org.onosproject.net.driver.TestBehaviour"
-                   impl="org.onosproject.net.driver.TestBehaviourImpl"/>
         <behaviour api="org.onosproject.net.driver.TestBehaviourTwo"
                    impl="org.onosproject.net.driver.TestBehaviourTwoImpl"/>